בדף הזה מוסבר איך בנויה מדיניות SELinux. מדיניות SELinux מורכבת משילוב של מדיניות ליבה של AOSP (פלטפורמה) ומדיניות ספציפית למכשיר (ספק). תהליך בניית מדיניות SELinux ב-Android מגרסה 4.4 עד גרסה 7.0 מיזג את כל חלקי ה-sepolicy ואז יצר קבצים מונוליטיים בספריית הבסיס. המשמעות היא שספקי 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 policy compiler (host executables:checkpolicy
,checkmodule
, anddispol
). Depends onlibsepol
.
-
-
system/sepolicy
: הגדרות מדיניות הליבה של Android SELinux, כולל קבצי מדיניות והקשרים. הלוגיקה העיקרית של בניית sepolicy נמצאת גם כאן (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
הספציפי למכשיר. משתנה הגרסה הגלובלי הזה מכיל רשימה של ספריות שמציינות את הסדר שבו יתבצע החיפוש אחר קובצי מדיניות נוספים.
לדוגמה, ספק 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 נמצא במצב מתירני (ולא במצב מחייב). תהליך האתחול מבצע את המשימות הבאות:
- טוען
sepolicy
קבצים מ-ramdisk לליבה דרך/sys/fs/selinux/load
. - הפקודה מעבירה את SELinux למצב אכיפה.
- מריצים את הפקודה
re-exec()
כדי להחיל את כלל הדומיין של SELinux על עצמו.
כדי לקצר את זמן האתחול, צריך לבצע את התהליך re-exec()
init
בהקדם האפשרי.
Android מגרסה 8.0 ואילך
ב-Android 8.0, מדיניות SELinux מחולקת לרכיבי פלטפורמה וספק כדי לאפשר עדכוני מדיניות עצמאיים של פלטפורמה/ספק תוך שמירה על תאימות.
פלטפורמת sepolicy מחולקת לחלקים פרטיים וציבוריים כדי לייצא סוגים ומאפיינים ספציפיים לכותבי מדיניות של ספקים. מובטח שסוגים או מאפיינים ציבוריים של הפלטפורמה יישמרו כממשקי API יציבים לגרסה נתונה של הפלטפורמה. אפשר להבטיח תאימות עם סוגים או מאפיינים קודמים של הפלטפורמה בכמה גרסאות באמצעות קובצי מיפוי של הפלטפורמה.
תהליך ה-build ל-Android מגרסה 8.0
מדיניות SELinux ב-Android 8.0 נוצרת על ידי שילוב של חלקים מ-/system
ומ-/vendor
. הלוגיקה להגדרה נכונה נמצאת ב
/platform/system/sepolicy/Android.mk
.
המדיניות קיימת במיקומים הבאים:
מיקום | הכלה |
---|---|
system/sepolicy/public |
sepolicy API של הפלטפורמה |
system/sepolicy/private |
פרטי ההטמעה של הפלטפורמה (ספקים יכולים להתעלם) |
system/sepolicy/vendor |
קבצים של מדיניות והקשר שספקים יכולים להשתמש בהם (הספקים יכולים להתעלם מהם אם הם רוצים) |
BOARD_SEPOLICY_DIRS |
Vendor sepolicy |
BOARD_ODM_SEPOLICY_DIRS (Android מגרסה 9 ואילך) |
Odm sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
System_ext's sepolicy API |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
פרטי הטמעה של System_ext (ספקים יכולים להתעלם) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
Product's sepolicy API |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android מגרסה 11 ואילך) |
פרטי הטמעה של מוצרים (ספקים יכולים להתעלם) |
מערכת ה-build לוקחת את המדיניות הזו ומפיקה רכיבי מדיניות של system, system_ext, product, vendor ו-odm במחיצה המתאימה. איך פותרים את הבעיה:
- המרת כללי מדיניות לפורמט של SELinux Common Intermediate Language (CIL), באופן ספציפי:
- מדיניות פלטפורמה ציבורית (מערכת + מערכת_ext + מוצר)
- מדיניות פרטית וציבורית משולבת
- ציבורי + ספק ו
BOARD_SEPOLICY_DIRS
מדיניות
- הוספת גרסאות למדיניות שסופקה על ידי הציבור כחלק ממדיניות הספק.
הפעולה מתבצעת באמצעות מדיניות ה-CIL הציבורית שנוצרה, כדי להודיע למדיניות המשולבת הציבורית + הספק +
BOARD_SEPOLICY_DIRS
אילו חלקים צריכים להפוך למאפיינים שיקושרו למדיניות הפלטפורמה. - יצירת קובץ מיפוי שמקשר בין חלקי הפלטפורמה והספק. בשלב הראשון, המדיניות הזו מקשרת בין הסוגים ממדיניות הפרטיות לבין המאפיינים התואמים במדיניות הספק. בהמשך, היא תשמש גם כבסיס לקובץ שיתעדכן בגרסאות עתידיות של הפלטפורמה, כדי לאפשר תאימות לטירגוט של מדיניות הספק בגרסה הזו של הפלטפורמה.
- שילוב של קובצי מדיניות (תיאור של פתרונות במכשיר ופתרונות שעברו קומפילציה מראש).
- שילוב של מיפוי, פלטפורמה ומדיניות ספקים.
- קומפילציה של קובץ מדיניות בינארי של פלט.
מדיניות ציבורית של SELinux בפלטפורמה
מדיניות ה-SELinux הציבורית של הפלטפורמה כוללת את כל מה שמוגדר ב-
system/sepolicy/public
. הפלטפורמה יכולה להניח שהסוגים והמאפיינים שמוגדרים במסגרת מדיניות ציבורית הם ממשקי API יציבים לגרסה נתונה של הפלטפורמה. החלק הזה הוא חלק ממדיניות האבטחה (sepolicy) שמיוצאת על ידי הפלטפורמה שבה מפתחי מדיניות של ספקים (כלומר, מכשירים) יכולים לכתוב מדיניות נוספת ספציפית למכשיר.
הסוגים הם בעלי גרסאות בהתאם לגרסת המדיניות שקבצי הספק נכתבים לפיה, שמוגדרת על ידי משתנה ה-build PLATFORM_SEPOLICY_VERSION
. לאחר מכן, המדיניות הציבורית עם ניהול הגרסאות נכללת במדיניות הספק (בגרסה המקורית שלה) ובמדיניות הפלטפורמה. לכן,
המדיניות הסופית כוללת את מדיניות הפלטפורמה הפרטית, את מדיניות ה-sepolicy הציבורית הנוכחית של הפלטפורמה, את המדיניות הספציפית למכשיר ואת המדיניות הציבורית עם הגרסה שתואמת לגרסת הפלטפורמה שלפיה נכתבה מדיניות המכשיר.
מדיניות פרטית של SELinux בפלטפורמה
מדיניות הפרטיות של הפלטפורמה כוללת את כל מה שמוגדר בקטע
/system/sepolicy/private
. החלק הזה של המדיניות כולל סוגים, הרשאות ומאפיינים שנדרשים לפונקציונליות של הפלטפורמה. ההגדרות האלה לא מיוצאות לכותבי המדיניות vendor/device
. כותבי מדיניות שאינם פלטפורמה לא יכולים לכתוב את הרחבות המדיניות שלהם על סמך סוגים, מאפיינים או כללים שמוגדרים במדיניות הפרטית של הפלטפורמה. בנוסף, יכול להיות שיהיה אפשר לשנות את הכללים האלה, או שהם ייעלמו כחלק מעדכון של המסגרת בלבד.
מיפוי פרטי של פלטפורמה
מיפוי הפרטיות של הפלטפורמה כולל הצהרות מדיניות שממפות את המאפיינים שנחשפים במדיניות הציבורית של הפלטפורמה בגרסאות הקודמות של הפלטפורמה לסוגים הקונקרטיים שמשמשים במדיניות הציבורית הנוכחית של הפלטפורמה. כך אפשר לוודא שמדיניות הספק שנכתבה על סמך מאפיינים ציבוריים של הפלטפורמה מגרסאות קודמות של מדיניות האבטחה הציבורית של הפלטפורמה תמשיך לפעול. הגרסאות מבוססות על PLATFORM_SEPOLICY_VERSION
משתנה ה-build
שמוגדר ב-AOSP לגרסת פלטפורמה נתונה. קיים קובץ מיפוי נפרד לכל גרסה קודמת של הפלטפורמה, שממנה הפלטפורמה הזו צפויה לקבל מדיניות של ספקים. פרטים נוספים זמינים במאמר בנושא תאימות.
Android מגרסה 11 ואילך
system_ext ו-product sepolicy
ב-Android 11, נוספו מדיניות system_ext ומדיניות מוצרים. בדומה למדיניות הפלטפורמה, מדיניות system_ext ומדיניות המוצר מחולקות למדיניות ציבורית ולמדיניות פרטית.
מדיניות ציבורית מיוצאת לספק. הסוגים והמאפיינים הופכים ל-API יציב, ומדיניות הספק יכולה להתייחס לסוגים ולמאפיינים במדיניות הציבורית. הסוגים הם
עם מספור גרסאות לפי PLATFORM_SEPOLICY_VERSION
, ומדיניות עם מספור גרסאות
כלולה במדיניות הספק. המדיניות המקורית כלולה בכל אחד מהמחיצות system_ext ו-product.
מדיניות הפרטיות מכילה סוגים, הרשאות ומאפיינים שנדרשים לפונקציונליות של מחיצות system_ext ושל מוצרים, ורלוונטיים רק ל-system_ext ולמוצרים. מדיניות הפרטיות לא גלויה לספק, מה שאומר שהכללים האלה הם פנימיים ומותר לשנות אותם.
מיפוי של system_ext ומוצרים
מותר לייצא את הסוגים הציבוריים הייעודיים של system_ext ו-product אל vendor. עם זאת, כל שותף אחראי לוודא שהמערכת שלו תהיה תואמת. לצורך תאימות, שותפים יכולים לספק קובצי מיפוי משלהם שממפים את המאפיינים עם הגרסאות של גרסאות קודמות לסוגים קונקרטיים שמשמשים במדיניות ה-SE הנוכחית שזמינה לציבור.
- כדי להתקין קובץ מיפוי עבור 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
.