מאמר זה מכסה כיצד בנויה מדיניות 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
: -
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
במכשיר:
קובץ 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 ואילך מכילים בדרך כלל את הקבצים הבאים הקשורים ל-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 Common Intermediate Language (CIL), במיוחד:
- מדיניות פלטפורמה ציבורית (מערכת + system_ext + מוצר)
- מדיניות פרטית + ציבורית משולבת
- ציבורי + ספק ומדיניות
BOARD_SEPOLICY_DIRS
- גירסת הפוליסה הנמסרת על ידי הציבור כחלק ממדיניות הספקים. נעשה על ידי שימוש במדיניות ה-CIL הציבורית שהופקה כדי ליידע את המדיניות המשולבת של הציבור + הספק +
BOARD_SEPOLICY_DIRS
לגבי אילו חלקים יש להפוך למאפיינים שיקושרו למדיניות הפלטפורמה. - יצירת קובץ מיפוי המקשר בין הפלטפורמה לחלקי הספק. בתחילה, זה רק מקשר את הסוגים מהמדיניות הציבורית עם התכונות המתאימות במדיניות הספק; מאוחר יותר הוא גם יספק את הבסיס לקובץ המתוחזק בגרסאות פלטפורמה עתידיות, ויאפשר תאימות עם מדיניות הספקים המכוונת לגירסת פלטפורמה זו.
- שילוב קובצי מדיניות (תאר גם פתרונות במכשיר וגם פתרונות מהודרים מראש).
- שלב מיפוי, פלטפורמה ומדיניות ספקים.
- הידור קובץ מדיניות בינארי של פלט.
- גם
/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
אינם קיימים. או ששניהם קיימים וזהים.
בניית מדיניות 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 במחיצה המתאימה. השלבים כוללים:
מדיניות 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
.
אם אחד מהם שונה, init
נופל בחזרה לנתיב ההידור במכשיר. ראה system/core/init/selinux.cpp
לפרטים נוספים.