בניית מדיניות SELinux

מאמר זה מכסה כיצד בנויה מדיניות SELinux. מדיניות SELinux בנויה מהשילוב של מדיניות ליבה של AOSP (פלטפורמה) ומדיניות ספציפית למכשיר (ספק). זרימת בניית המדיניות של SELinux עבור אנדרואיד 4.4 עד אנדרואיד 7.0 מיזגה את כל קטעי המדיניות ואז יצרה קבצים מונוליטיים בספריית השורש. המשמעות היא שספקי SoC ויצרני ODM שינו את boot.img (עבור התקנים שאינם A/B) או system.img (עבור התקני A/B) בכל פעם ששונתה המדיניות.

ב-Android 8.0 ואילך, מדיניות הפלטפורמה והספק נבנית בנפרד. SOCs ויצרני OEM יכולים לעדכן את חלקי המדיניות שלהם, לבנות את התמונות שלהם (כגון, vendor.img ו- boot.img ), ואז לעדכן את התמונות האלה ללא תלות בעדכוני הפלטפורמה.

עם זאת, מכיוון שקובצי מדיניות SELinux מודולריים מאוחסנים במחיצות /vendor , תהליך init חייב לעלות את המחיצות של המערכת והספק מוקדם יותר כדי שיוכל לקרוא קבצי SELinux מהמחיצות הללו ולמזג אותם עם קובצי SELinux הליבה בספריית המערכת (לפני טעינתם לתוך הגרעין).

קבצי המקור

ההיגיון לבניית SELinux נמצא בקבצים הבאים:

  • external/selinux : פרויקט SELinux חיצוני, המשמש לבניית כלי עזר של שורת הפקודה של HOST כדי להרכיב מדיניות ותוויות של SELinux.
    • external/selinux/libselinux : אנדרואיד משתמש רק בתת-קבוצה של פרויקט libselinux החיצוני יחד עם כמה התאמות אישיות ספציפיות לאנדרואיד. לפרטים, עיין external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : קבע אם הקשר אבטחה חוקי עבור מדיניות בינארית נתונה (קובץ הפעלה מארח).
      • libsepol : ספריית SELinux למניפולציה של מדיניות אבטחה בינארית (ספרייה סטטית/משותפת מארח, ספריית יעד סטטית).
    • external/selinux/checkpolicy : מהדר מדיניות SELinux (קובצי הפעלה מארח: checkpolicy , checkmodule ו- dispol ). תלוי ב- libsepol .
  • system/sepolicy : תצורות מדיניות ליבה של Android SELinux, כולל הקשרים וקובצי מדיניות. הלוגיקה העיקרית של בניית sepolicy נמצאת גם כאן ( system/sepolicy/Android.mk ).

לפרטים נוספים על הקבצים ב- system/sepolicy יישום SELinux .

אנדרואיד 7.0 ומעלה

סעיף זה מכסה כיצד מדיניות SELinux בנויה באנדרואיד 7.x ואילך.

בניית מדיניות SELinux

מדיניות SELinux נוצרת על ידי שילוב של מדיניות הליבה של AOSP עם התאמות אישיות ספציפיות למכשיר. לאחר מכן המדיניות המשולבת מועברת למהדר המדיניות ולבודקים שונים. התאמה אישית ספציפית למכשיר נעשית באמצעות המשתנה BOARD_SEPOLICY_DIRS המוגדר בקובץ Boardconfig.mk הספציפי למכשיר. משתנה בנייה גלובלי זה מכיל רשימה של ספריות המציינות את הסדר שבו לחפש קובצי מדיניות נוספים.

לדוגמה, ספק SoC ו-ODM עשויים להוסיף כל אחד ספריה, אחת להגדרות הספציפיות ל-SoC ואחרת להגדרות ספציפיות למכשיר, כדי ליצור את תצורות ה-SELinux הסופיות עבור מכשיר נתון:

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

התוכן של קבצי file_contexts ב- system/sepolicy וב- BOARD_SEPOLICY_DIRS משורשרים כדי ליצור את הקובץ file_contexts.bin במכשיר:

תמונה זו מציגה את היגיון הבנייה של SELinux עבור אנדרואיד 7.x.
איור 1 . היגיון בניית SELinux

קובץ sepolicy מורכב מקובצי מקור מרובים:

  • הטקסט הפשוט policy.conf נוצר על ידי שרשור security_classes , initial_sids , קבצי *.te , genfs_contexts ו- port_contexts בסדר זה.
  • עבור כל קובץ (כגון security_classes ), התוכן שלו הוא שרשור הקבצים עם אותו שם תחת system/sepolicy/ ו- BOARDS_SEPOLICY_DIRS .
  • ה- policy.conf נשלח אל מהדר SELinux לבדיקת תחביר וקומפילציה לפורמט בינארי כ- sepolicy במכשיר.
    תמונה זו מציגה את הקבצים שיוצרים את קובץ המדיניות של SELinux עבור אנדרואיד 7.x.
    איור 2 . קובץ מדיניות SELinux

קבצי SELinux

לאחר הקומפילציה, מכשירי אנדרואיד המריצים 7.x ואילך מכילים בדרך כלל את הקבצים הבאים הקשורים ל-SELinux:

  • selinux_version
  • sepolicy: פלט בינארי לאחר שילוב קובצי מדיניות (כגון, security_classes , initial_sids ו- *.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

לפרטים נוספים, ראה יישום SELinux .

אתחול SELinux

כאשר המערכת מאתחלת, SELinux נמצא במצב מתירני (ולא במצב אכיפה). תהליך ה-init מבצע את המשימות הבאות:

  • טוען קבצי sepolicy מ-ramdisk לתוך הליבה דרך /sys/fs/selinux/load .
  • מעביר את SELinux למצב אכיפה.
  • מפעיל את re-exec() כדי להחיל את כלל התחום של SELinux על עצמו.

כדי לקצר את זמן האתחול, בצע את re-exec() בתהליך init בהקדם האפשרי.

אנדרואיד 8.0 ומעלה

באנדרואיד 8.0, מדיניות SELinux מפוצלת לרכיבי פלטפורמה וספקים כדי לאפשר עדכוני מדיניות פלטפורמה/ספק עצמאיים תוך שמירה על תאימות.

הפלטפורמה sepolicy מפוצלת עוד יותר לחלקים פרטיים של פלטפורמה ולחלקים ציבוריים של פלטפורמה כדי לייצא סוגים ומאפיינים ספציפיים לכותבי מדיניות של ספקים. מובטח שהסוגים/מאפיינים הציבוריים של הפלטפורמה יישמרו כממשקי API יציבים עבור גרסת פלטפורמה נתונה. ניתן להבטיח תאימות לסוגים/מאפיינים ציבוריים של פלטפורמה קודמים עבור מספר גרסאות באמצעות קובצי מיפוי פלטפורמה.

פלטפורמת מדיניות ציבורית

הפלטפורמה public sepolicy כוללת את כל מה שמוגדר תחת system/sepolicy/public . הפלטפורמה יכולה להניח שהסוגים והתכונות שהוגדרו במסגרת מדיניות ציבורית הם ממשקי API יציבים עבור גרסת פלטפורמה נתונה. זה מהווה את החלק של ה-sepolicy שמיוצא לפי פלטפורמה שעליו מפתחי מדיניות ספקים (כלומר מכשיר) יכולים לכתוב מדיניות נוספת ספציפית למכשיר.

סוגים מגויסים בהתאם לגרסת המדיניות שלפיה נכתבים קבצי הספק, המוגדרת על ידי משתנה הבנייה PLATFORM_SEPOLICY_VERSION . המדיניות הציבורית המנוסחת נכללת אז במדיניות הספקים ו(בצורתה המקורית) במדיניות הפלטפורמה. לפיכך, המדיניות הסופית כוללת את מדיניות הפלטפורמה הפרטית, המדיניות הציבורית של הפלטפורמה הנוכחית, המדיניות הספציפית למכשיר, והמדיניות הציבורית המנוסחת התואמת לגרסת הפלטפורמה שכנגדה נכתבה מדיניות המכשיר.

פלטפורמת מדיניות פרטית

הפלטפורמה הפרטית sepolicy כוללת את כל מה שמוגדר תחת /system/sepolicy/private . חלק זה של המדיניות יוצר סוגים, הרשאות ותכונות לפלטפורמה בלבד הנדרשים לפונקציונליות הפלטפורמה. אלה אינם מיוצאים לכותבי מדיניות vendor/device . לכותבי מדיניות שאינם פלטפורמה אסור לכתוב את הרחבות המדיניות שלהם על סמך סוגים/מאפיינים/כללים המוגדרים במדיניות הפרטית של הפלטפורמה. יתר על כן, מותר לשנות כללים אלה או עשויים להיעלם כחלק מעדכון מסגרת בלבד.

מיפוי פרטי פלטפורמה

המיפוי הפרטי של הפלטפורמה כולל הצהרות מדיניות הממפות את התכונות שנחשפו במדיניות ציבורית של הפלטפורמה של גרסאות הפלטפורמה הקודמות לסוגים הקונקרטיים ששימשו במדיניות ציבורית של הפלטפורמה הנוכחית. זה מבטיח שמדיניות הספקים שנכתבה על סמך מאפיינים ציבוריים של הפלטפורמה מהגרסה הקודמת של מדיניות ה-sepolicy של הפלטפורמה ממשיכה לפעול. ניהול הגרסאות מבוסס על משתנה הבנייה PLATFORM_SEPOLICY_VERSION שנקבע ב-AOSP עבור גרסת פלטפורמה נתונה. קיים קובץ מיפוי נפרד עבור כל גרסת פלטפורמה קודמת שממנה צפויה פלטפורמה זו לקבל את מדיניות הספקים. לפרטים נוספים, ראה תאימות .

אנדרואיד 11 ומעלה

system_ext ומדיניות המוצר

ב-Android 11, מתווספות מדיניות system_ext ומדיניות מוצר. כמו הפלטפורמה sepolicy, מדיניות system_ext ומדיניות המוצר מחולקות למדיניות ציבורית ומדיניות פרטית.

מדיניות ציבורית מיוצאת לספק. סוגים ותכונות הופכים לממשק API יציב, ומדיניות הספקים יכולה להתייחס לסוגים ותכונות במדיניות הציבורית. סוגים מנוסחים לפי PLATFORM_SEPOLICY_VERSION , והמדיניות המנוסחת כלולה במדיניות הספקים. המדיניות המקורית כלולה בכל אחת ממחיצות system_ext ומחיצות המוצר.

המדיניות הפרטית מכילה סוגים, הרשאות ותכונות של system_ext ומוצר בלבד, הנדרשים לפונקציונליות של system_ext ומחיצות המוצר. מדיניות פרטית אינה נראית לעיני הספק, מה שמרמז שהכללים הללו הם פנימיים ומותר לשינוי.

system_ext ומיפוי מוצר

system_ext והמוצר רשאים לייצא את הסוגים הציבוריים הייעודיים שלהם לספק. עם זאת, האחריות לשמור על תאימות היא על כל אחד מבני הזוג. לצורך תאימות, שותפים יכולים לספק קובצי מיפוי משלהם הממפים את תכונות הגירסאות של הגירסאות הקודמות לסוגים קונקרטיים המשמשים במדיניות ציבורית נוכחית.

  • כדי להתקין קובץ מיפוי עבור system_ext, הצב קובץ cil המכיל את פרטי המיפוי הרצויים אל {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , ולאחר מכן הוסף system_ext_{ver}.cil ל- PRODUCT_PACKAGES .
  • כדי להתקין קובץ מיפוי למוצר, הצב קובץ cil המכיל את פרטי המיפוי הרצויים אל {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , ולאחר מכן הוסף product_{ver}.cil ל- PRODUCT_PACKAGES .
  • עיין בדוגמה שמוסיפה קובץ מיפוי של מחיצת המוצר של מכשיר redbull.

    בניית מדיניות SELinux

    מדיניות SELinux באנדרואיד 8.0 נוצרת על ידי שילוב של חלקים מ- /system ו- /vendor . ההיגיון להגדרה זה כראוי נמצא ב- /platform/system/sepolicy/Android.mk .

    המדיניות קיימת במיקומים הבאים:

    מקום מכיל
    system/sepolicy/public ממשק API של sepolicy של הפלטפורמה
    system/sepolicy/private פרטי הטמעת פלטפורמה (ספקים יכולים להתעלם)
    system/sepolicy/vendor קובצי מדיניות והקשר שבהם הספקים יכולים להשתמש (ספקים יכולים להתעלם אם רוצים)
    BOARD_SEPOLICY_DIRS מדיניות הספק
    BOARD_ODM_SEPOLICY_DIRS (אנדרואיד 9 ומעלה) Odm sepolicy
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (אנדרואיד 11 ומעלה) ממשק API של sepolicy של System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (אנדרואיד 11 ומעלה) פרטי הטמעת System_ext (ספקים יכולים להתעלם)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (אנדרואיד 11 ומעלה) ממשק API של sepolicy של המוצר
    PRODUCT_PRIVATE_SEPOLICY_DIRS (אנדרואיד 11 ומעלה) פרטי הטמעת מוצר (ספקים יכולים להתעלם)

    מערכת ה-build לוקחת מדיניות זו ומייצרת רכיבי מדיניות system, system_ext, מוצר, ספק ו-odm במחיצה המתאימה. השלבים כוללים:

    1. המרת מדיניות לפורמט SELinux Common Intermediate Language (CIL), במיוחד:
      1. מדיניות פלטפורמה ציבורית (מערכת + system_ext + מוצר)
      2. מדיניות פרטית + ציבורית משולבת
      3. ציבורי + ספק ומדיניות BOARD_SEPOLICY_DIRS
    2. גירסת הפוליסה הנמסרת על ידי הציבור כחלק ממדיניות הספקים. נעשה על ידי שימוש במדיניות ה-CIL הציבורית שהופקה כדי ליידע את המדיניות המשולבת של הציבור + הספק + BOARD_SEPOLICY_DIRS לגבי אילו חלקים יש להפוך למאפיינים שיקושרו למדיניות הפלטפורמה.
    3. יצירת קובץ מיפוי המקשר בין הפלטפורמה לחלקי הספק. בתחילה, זה רק מקשר את הסוגים מהמדיניות הציבורית עם התכונות המתאימות במדיניות הספק; מאוחר יותר הוא גם יספק את הבסיס לקובץ המתוחזק בגרסאות פלטפורמה עתידיות, ויאפשר תאימות עם מדיניות הספקים המכוונת לגירסת פלטפורמה זו.
    4. שילוב קובצי מדיניות (תאר גם פתרונות במכשיר וגם פתרונות מהודרים מראש).
      1. שלב מיפוי, פלטפורמה ומדיניות ספקים.
      2. הידור קובץ מדיניות בינארי של פלט.

    מדיניות SELinux שהוגדרה מראש

    לפני init מפעיל את SELinux, init אוסף את כל קבצי ה-CIL ממחיצות ( system , system_ext , product , vendor ו- odm ) ומרכיב אותם למדיניות בינארית, הפורמט שניתן לטעון לליבה. מכיוון שההידור לוקח זמן (בדרך כלל 1-2 שניות), קובצי ה-CIL נערכים מראש בזמן הבנייה וממוקמים ב- /vendor/etc/selinux/precompiled_sepolicy או /odm/etc/selinux/precompiled_sepolicy , יחד עם ה-sha256 hashes של קבצי ה-CIL הקלט. בזמן ריצה, init בודק אם אחד מקובץ המדיניות עודכן על ידי השוואת הגיבובים. אם שום דבר לא השתנה, init טוען את המדיניות המורכבת מראש. אם לא, init מבצע קומפילציה תוך כדי שימוש ומשתמש בו במקום הקומפילציה מראש.

    ליתר דיוק, נעשה שימוש במדיניות המורכבת מראש אם מתקיימים כל התנאים הבאים. כאן, {partition} מייצגת את המחיצה שבה קיימת מדיניות הקומפילציה מראש: vendor או odm .

    • גם /system/etc/selinux/plat_sepolicy_and_mapping.sha256 וגם /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 קיימים והם זהים.
    • גם /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 וגם /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 אינם קיימים. או ששניהם קיימים וזהים.
    • גם /product/etc/selinux/product_sepolicy_and_mapping.sha256 וגם /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 אינם קיימים. או ששניהם קיימים וזהים.

    אם אחד מהם שונה, init נופל בחזרה לנתיב ההידור במכשיר. ראה system/core/init/selinux.cpp לפרטים נוספים.