בדף הזה מוסבר איך נוצרת מדיניות SELinux. מדיניות SELinux מורכבת משילוב של מדיניות הליבה של AOSP (פלטפורמה) ומדיניות ספציפית למכשיר (ספק). תהליך ה-build של מדיניות SELinux ב-Android 4.4 עד Android 7.0 מיזג את כל קטעי ה-sepolicy ויצר קובצי monolith בספריית השורש. המשמעות היא שמוכרי SoC ויצרני ODM שיניבו את הערך של boot.img
(למכשירים שאינם A/B) או את הערך של system.img
(למכשירי A/B) בכל פעם שהמדיניות תשתנה.
ב-Android מגרסה 8.0 ואילך, המדיניות של הפלטפורמה והמדיניות של הספק נוצרות בנפרד.
SOC ו-OEM יכולים לעדכן את החלקים שלהם במדיניות, ליצור את התמונות שלהם (כמו vendor.img
ו-boot.img
) ולאחר מכן לעדכן את התמונות האלה בנפרד מהעדכונים של הפלטפורמה.
עם זאת, מאחר שקובצי המדיניות של SELinux מודולריים מאוחסנים במחיצות /vendor
, התהליך init
צריך לטעון מראש את המחיצות של המערכת והספק כדי שיוכל לקרוא קובצי SELinux מהמחיצות האלה ולמזג אותם עם קובצי הליבה של SELinux בתיקיית המערכת (לפני הטעינה שלהם בליבה).
קובצי מקור
הלוגיקה לבניית SELinux נמצאת בקבצים הבאים:
-
external/selinux
: פרויקט SELinux חיצוני, המשמש ליצירת כלי שורת פקודה של HOST כדי לקמפל את המדיניות והתוויות של SELinux.-
external/selinux/libselinux
: ב-Android נעשה שימוש רק בקבוצת משנה של הפרויקט החיצוניlibselinux
, יחד עם כמה התאמות אישיות ספציפיות ל-Android. פרטים נוספים זמינים במאמרexternal/selinux/README.android
. -
external/selinux/libsepol
: -
external/selinux/checkpolicy
: קומפילטור של מדיניות SELinux (קובצי הפעלה של המארח:checkpolicy
,checkmodule
ו-dispol
). תלוי ב-libsepol
.
-
-
system/sepolicy
: הגדרות הליבה של מדיניות SELinux ב-Android, כולל הקשרים וקובצי מדיניות. גם הלוגיקה העיקרית של build של מדיניות האבטחה נמצאת כאן (system/sepolicy/Android.mk
).
פרטים נוספים על הקבצים מופיעים במאמר system/sepolicy
הטמעת SELinux.
Android מגרסה 7.x ומטה
בקטע הזה נסביר איך המדיניות של SELinux נוצרת ב-Android 7.x וגרסאות מוקדמות יותר.
תהליך build ל-Android מגרסה 7.x ומטה
מדיניות SELinux נוצרת על ידי שילוב של מדיניות הליבה של AOSP עם התאמות ספציפיות למכשיר. לאחר מכן, המדיניות המשולבת מועברת למהדר המדיניות ולבודקים שונים. התאמה אישית ספציפית למכשיר מתבצעת באמצעות המשתנה BOARD_SEPOLICY_DIRS
שמוגדר בקובץ Boardconfig.mk
הספציפי למכשיר. משתנה ה-build הגלובלי הזה מכיל רשימה של ספריות שמציינות את הסדר שבו צריך לחפש קובצי מדיניות נוספים.
לדוגמה, ספק 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
במכשיר:

איור 1. לוגיקה של build של SELinux.
קובץ sepolicy
מורכב מכמה קובצי מקור:
- הטקסט הפשוט
policy.conf
נוצר על ידי שרשור של קבציםsecurity_classes
,initial_sids
,*.te
,genfs_contexts
ו-port_contexts
בסדר הזה. - לכל קובץ (כמו
security_classes
), התוכן שלו הוא שרשור של הקבצים עם אותו שם ב-system/sepolicy/
וב-BOARDS_SEPOLICY_DIRS
. - ה-
policy.conf
נשלח למהדר של SELinux לבדיקה של התחביר, ומתורגם לפורמט בינארי בתורsepolicy
במכשיר.איור 2. קובץ מדיניות של SELinux.
קובצי SELinux
לאחר הידור, מכשירי Android עם גרסת 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
בהקדם האפשרי.
Android מגרסה 8.0 ואילך
ב-Android 8.0, מדיניות SELinux מחולקת לרכיבים של פלטפורמה ורכיבים של ספק כדי לאפשר עדכונים עצמאיים של מדיניות הפלטפורמה או של מדיניות הספק, תוך שמירה על תאימות.
מדיניות האבטחה של הפלטפורמה מחולקת לחלקים פרטיים ולחלקים ציבוריים כדי לייצא סוגים ומאפיינים ספציפיים לכותבי מדיניות של ספקים. אנחנו מתחייבים לשמור על הסוגים או המאפיינים הציבוריים של הפלטפורמה כממשקי API יציבים בגרסה מסוימת של הפלטפורמה. אפשר להבטיח תאימות עם סוגים או מאפיינים ציבוריים קודמים של הפלטפורמה בכמה גרסאות באמצעות קובצי מיפוי של הפלטפורמה.
תהליך build ל-Android מגרסה 8.0
מדיניות SELinux ב-Android 8.0 נוצרת על ידי שילוב של חלקים מ-/system
ומ-/vendor
. הלוגיקה להגדרה המתאימה מפורטת בקטע
/platform/system/sepolicy/Android.mk
.
המדיניות קיימת במיקומים הבאים:
מיקום | השירים הכלולים |
---|---|
system/sepolicy/public |
ה-API של מדיניות האבטחה בפלטפורמה |
system/sepolicy/private |
פרטי הטמעת הפלטפורמה (ספקים יכולים להתעלם מהם) |
system/sepolicy/vendor |
קבצי מדיניות והקשר שספקים יכולים להשתמש בהם (ספקים יכולים להתעלם מהם אם הם רוצים) |
BOARD_SEPOLICY_DIRS |
מדיניות האבטחה של הספק |
BOARD_ODM_SEPOLICY_DIRS (Android מגרסה 9 ואילך) |
Odm sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
ממשק ה-API של sepolicy ב-System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
פרטי הטמעה של System_ext (ספקים יכולים להתעלם מהם) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
ממשק ה-API של מדיניות האבטחה של המוצר |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
פרטי הטמעת המוצר (ספקים יכולים להתעלם מהם) |
מערכת ה-build משתמשת במדיניות הזו כדי ליצור רכיבי מדיניות של system, system_ext, product, vendor ו-odm במחיצה המתאימה. השלבים כוללים:
- המרת כללי המדיניות לפורמט SELinux Common Intermediate Language (CIL), ובמיוחד:
- מדיניות פלטפורמה ציבורית (system + system_ext + product)
- מדיניות פרטית וציבורית משולבת
- המדיניות של public + vendor ו-
BOARD_SEPOLICY_DIRS
- יצירת גרסאות למדיניות שסופקו על ידי הציבור כחלק ממדיניות הספק.
כדי לעשות זאת, משתמשים במדיניות ה-CIL הציבורית שנוצרה כדי להנחות את המדיניות המשולבת של הציבור, הספק ו-
BOARD_SEPOLICY_DIRS
לגבי החלקים שצריך להפוך למאפיינים שייקוש למדיניות הפלטפורמה. - יצירת קובץ מיפוי שמקשר בין החלקים של הפלטפורמה לבין החלקים של הספק. בשלב הראשון, הקישור הזה רק מקשר את הסוגים מהמדיניות הציבורית למאפיינים התואמים במדיניות הספק. בהמשך, הוא גם יספק את הבסיס לקובץ ששמור בגרסאות עתידיות של הפלטפורמה, ויאפשר תאימות למדיניות הספק שמטרגטת את גרסת הפלטפורמה הזו.
- שילוב של קובצי מדיניות (תיאור של פתרונות במכשיר ופתרונות שנוצרו מראש).
- שילוב של מדיניות המיפוי, הפלטפורמה והספק.
- קומפילציה של קובץ המדיניות הבינארי של הפלט.
מדיניות אבטחה ציבורית של פלטפורמה
מדיניות האבטחה הציבורית של הפלטפורמה כוללת את כל מה שמוגדר בקטע
system/sepolicy/public
. הפלטפורמה יכולה להניח שהסוגים והמאפיינים שמוגדרים במדיניות הציבורית הם ממשקי API יציבים לגרסה מסוימת של הפלטפורמה. זהו החלק של מדיניות האבטחה (sepolicy) שמיוצא על ידי הפלטפורמה, שבו מפתחי המדיניות של הספק (כלומר המכשיר) יכולים לכתוב מדיניות נוספת ספציפית למכשיר.
הסוגים מחולקים לגרסאות בהתאם לגרסה של המדיניות שבה נכתבים קובצי הספק, כפי שמוגדר במשתנה ה-build PLATFORM_SEPOLICY_VERSION
. לאחר מכן, המדיניות הציבורית עם הגרסאות נכללת במדיניות הספק (בפורמט המקורי שלה) ובמדיניות הפלטפורמה. לכן, המדיניות הסופית כוללת את מדיניות הפלטפורמה הפרטית, את מדיניות האבטחה הציבורית הנוכחית של הפלטפורמה, את המדיניות הספציפית למכשיר ואת המדיניות הציבורית עם הגרסה התואמת לגרסה של הפלטפורמה שבה נכתבה מדיניות המכשיר.
מדיניות אבטחה פרטית של פלטפורמה
מדיניות האבטחה הפרטית של הפלטפורמה כוללת את כל מה שמוגדר בקטע
/system/sepolicy/private
. החלק הזה של המדיניות כולל את הסוגים, ההרשאות והמאפיינים של הפלטפורמה בלבד שנדרשים לפונקציונליות שלה. הם לא מיוצאים לכלי ליצירת כללי המדיניות של vendor/device
. כותבי מדיניות שלא קשורים לפלטפורמה לא יכולים לכתוב את תוספי המדיניות שלהם על סמך סוגים/מאפיינים/כללים שהוגדרו במדיניות האבטחה הפרטית של הפלטפורמה. בנוסף, מותר לשנות את הכללים האלה או שהם עשויים להיעלם כחלק מעדכון של המסגרת בלבד.
מיפוי פרטי של פלטפורמה
המיפוי הפרטי של הפלטפורמה כולל הצהרות מדיניות שממפות את המאפיינים שנחשפו במדיניות הציבורית של הפלטפורמה בגרסאות הקודמות של הפלטפורמה לסוגי הנתונים הספציפיים שמשמשים במדיניות האבטחה הציבורית הנוכחית של הפלטפורמה. כך תוכלו להבטיח שמדיניות הספק שנכתבה על סמך מאפיינים ציבוריים של הפלטפורמה מגרסאות הקודמות של מדיניות האבטחה הציבורית של הפלטפורמה תמשיך לפעול. ניהול הגרסאות מבוסס על משתנה ה-build PLATFORM_SEPOLICY_VERSION
שמוגדר ב-AOSP לגרסה מסוימת של הפלטפורמה. קיים קובץ מיפוי נפרד לכל גרסה קודמת של הפלטפורמה שממנה הפלטפורמה הזו אמורה לקבל את מדיניות הספק. מידע נוסף זמין בקטע תאימות.
Android מגרסה 11 ואילך
system_ext ו-product sepolicy
ב-Android 11 נוספות המדיניות system_ext והמדיניות של המוצר. בדומה למדיניות sepolicy של הפלטפורמה, המדיניות system_ext ומדיניות המוצר מחולקות למדיניות ציבורית ולמדיניות פרטית.
מדיניות הציבור מיוצאת לספק. סוגי מאפיינים הופכים ל-API יציב, ומדיניות הספק יכולה להפנות לסוגי מאפיינים במדיניות הציבורית. הסוגים מחולקים לגרסאות לפי PLATFORM_SEPOLICY_VERSION
, והמדיניות המחולקת לגרסאות כלולה במדיניות של הספק. המדיניות המקורית כלולה בכל מחיצה של system_ext ושל המוצר.
המדיניות הפרטית מכילה את סוגי הפריטים, ההרשאות והמאפיינים שנדרשים לפונקציונליות של המחיצות system_ext ושל המחיצות של המוצרים, ורק להם. המדיניות הפרטית לא גלויה לספק, כלומר הכללים האלה הם פנימיים וניתן לשנות אותם.
מיפוי של system_ext ומוצרים
האפשרות system_ext והאפשרות product מורשות לייצא את הסוגים הציבוריים הייעודיים שלהן אל הספק. עם זאת, האחריות לשמירה על תאימות היא של כל שותף בנפרד. לשם תאימות, שותפים יכולים לספק קובצי מיפוי משלהם שממפים את המאפיינים עם הגרסאות של הגרסאות הקודמות לסוגי נתונים ספציפיים שמשמשים את מדיניות האבטחה הציבורית הנוכחית.
- כדי להתקין קובץ מיפוי ל-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 שנוצרה מראש
לפני ש-init
מפעיל את SELinux, הוא אוסף את כל קובצי ה-CIL מהמחיצות (system
, system_ext
, product
, vendor
ו-odm
) ומעבד אותם למדיניות בינארית, הפורמט שאפשר לטעון לליבת ליבה.init
מאחר שהקמפיליציה נמשכת זמן מה (בדרך כלל שנייה או שתיים), קובצי ה-CIL מקובצים מראש בזמן ה-build וממוקמים ב-/vendor/etc/selinux/precompiled_sepolicy
או ב-/odm/etc/selinux/precompiled_sepolicy
, יחד עם גיבובי ה-sha256 של קובצי ה-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
.