מאמר זה מתאר כיצד אנדרואיד מטפלת בבעיות תאימות מדיניות עם פלטפורמות OTAs, שבהן הגדרות הפלטפורמה החדשות של SELinux עשויות להיות שונות מהגדרות SELinux הישנות של הספק.
עיצוב מדיניות SELinux המבוסס על טרבל שוקל הבחנה בינארית בין מדיניות של פלטפורמה וספק ; הסכימה הופכת מסובכת יותר אם מחיצות הספק מייצרות תלות, כגון platform
< vendor
< oem
.
באנדרואיד 8.0 ומעלה, המדיניות הגלובלית של SELinux מחולקת לרכיבים פרטיים וציבוריים. רכיבים ציבוריים מורכבים מהמדיניות ומהתשתית הנלווית, המובטחת זמינה עבור גרסת פלטפורמה. מדיניות זו תיחשף לכותבי מדיניות ספקים כדי לאפשר לספקים לבנות קובץ מדיניות ספקים, אשר בשילוב עם המדיניות המסופקת על ידי הפלטפורמה, מביא למדיניות תפקודית מלאה עבור מכשיר.
- עבור ניהול גרסאות, המדיניות הציבורית של הפלטפורמה המיוצאת תיכתב כמאפיינים .
- כדי להקל על כתיבת המדיניות, סוגים מיוצאים יומרו לתכונות עם גרסאות כחלק מתהליך בניית המדיניות. ניתן להשתמש בסוגים ציבוריים ישירות בהחלטות תיוג המסופקות על ידי קבצי ההקשרים של הספקים.
אנדרואיד שומרת על מיפוי בין סוגי בטון מיוצאים במדיניות הפלטפורמה לבין תכונות הגרסה המתאימות עבור כל גרסת פלטפורמה . זה מבטיח שכאשר אובייקטים מתויגים עם סוג, זה לא שובר התנהגות המובטחת על ידי המדיניות הציבורית של הפלטפורמה בגרסה קודמת. מיפוי זה מתוחזק על ידי שמירת קובץ מיפוי מעודכן עבור כל גרסת פלטפורמה , אשר שומר מידע על חברות תכונות עבור כל סוג המיוצא במדיניות ציבורית.
בעלות על אובייקט ותיוג
בעת התאמה אישית של מדיניות ב-Android 8.0 ואילך, בעלות חייבת להיות מוגדרת בבירור עבור כל אובייקט כדי להפריד בין מדיניות הפלטפורמה והספק. לדוגמה, אם הספק מציין את /dev/foo
והפלטפורמה אז מתגים את /dev/foo
ב-OTA עוקב, תהיה התנהגות לא מוגדרת. עבור SELinux, זה מתבטא כהתנגשות תיוג. לצומת ההתקן יכולה להיות רק תווית בודדת אשר פותרת את התווית שהוחלה לאחרונה. כתוצאה:
- תהליכים הזקוקים לגישה לתווית שהוחלה שלא בהצלחה יאבדו את הגישה למשאב.
- תהליכים שמקבלים גישה לקובץ עלולים להישבר בגלל שנוצר צומת המכשיר הלא נכון.
למאפייני המערכת יש גם פוטנציאל למתן שמות להתנגשויות שעלולות לגרום להתנהגות לא מוגדרת במערכת (כמו גם לתיוג SELinux). התנגשויות בין תוויות הפלטפורמה והספק יכולות להתרחש עבור כל אובייקט שיש לו תווית SELinux, כולל מאפיינים, שירותים, תהליכים, קבצים ושקעים. כדי להימנע מבעיות אלו, הגדירו בבירור בעלות על אובייקטים אלו.
בנוסף להתנגשויות התוויות, גם שמות סוגים/מאפיינים של SELinux עשויים להתנגש. התנגשות שם סוג/תכונה תמיד תגרום לשגיאת מהדר מדיניות.
מרווח שמות להקליד/תכונה
SELinux אינו מאפשר מספר הצהרות מאותו סוג/תכונה. מדיניות עם הצהרות כפולות תיכשל בהידור. כדי להימנע מהתנגשויות של שמות של סוגים ומאפיינים, כל הצהרות הספק צריכות להיות ברווחי שמות החל ב- np_
.
type foo, domain; → type np_foo, domain;
בעלות על נכסי מערכת ותווית תהליכים
הימנעות מהתנגשויות תיוג נפתרת בצורה הטובה ביותר באמצעות מרחבי שמות של נכסים. כדי לזהות בקלות מאפייני פלטפורמה ולמנוע התנגשויות שמות בעת שינוי שמות או הוספת מאפייני פלטפורמה מיוצאת, ודא שלכל נכסי הספק יש קידומות משלהם:
סוג נכס | קידומות מקובלות |
---|---|
מאפייני שליטה | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
ניתן לקריאה-כתיבה | vendor. |
לקריאה בלבד | ro.vendor. ro.boot. ro.hardware. |
מַתְמִיד | persist.vendor. |
הספקים יכולים להמשיך להשתמש ב- ro.boot.*
(שמגיע מה-cmdline של הליבה) וב- ro.hardware.*
(מאפיין ברור הקשור לחומרה).
לכל שירותי הספק בקבצי init rc צריך להיות vendor.
עבור שירותים בקבצי init rc של מחיצות שאינן מערכת. כללים דומים מיושמים על תוויות SELinux עבור מאפייני הספק ( vendor_
עבור מאפייני הספק).
בעלות על קובץ
מניעת התנגשויות עבור קבצים היא מאתגרת מכיוון שמדיניות הפלטפורמה והספק מספקות בדרך כלל תוויות לכל מערכות הקבצים. שלא כמו מתן שמות לסוגים, ריווח שמות של קבצים אינו מעשי מכיוון שרבים מהם נוצרים על ידי הקרנל. כדי למנוע התנגשויות אלה, עקוב אחר הנחיות השמות עבור מערכות קבצים בסעיף זה. עבור אנדרואיד 8.0, אלו הן המלצות ללא אכיפה טכנית. בעתיד, המלצות אלו יאכפו על ידי ה- Vendor Test Suite (VTS).
מערכת (/system)
רק תמונת המערכת חייבת לספק תוויות עבור /system
דרך file_contexts
, service_contexts
וכו'. אם מתווספות תוויות עבור /system
במדיניות /vendor
, ייתכן שעדכון OTA למסגרת בלבד לא יהיה אפשרי.
ספק (/ספק)
מדיניות AOSP SELinux כבר מסמנת חלקים ממחיצת vendor
איתה הפלטפורמה מקיימת אינטראקציה, מה שמאפשר לכתוב חוקי SELinux לתהליכי פלטפורמה כדי להיות מסוגלים לדבר ו/או לגשת לחלקים של מחיצת vendor
. דוגמאות:
/vendor נתיב | תווית מסופקת בפלטפורמה | תהליכי פלטפורמה בהתאם לתווית |
---|---|---|
/vendor(/. * )? | vendor_file | כל לקוחות HAL במסגרת, ueventd , וכו'. |
/vendor/framework(/. * )? | vendor_framework_file | dex2oat , appdomain וכו'. |
/vendor/app(/. * )? | vendor_app_file | dex2oat , installd , idmap וכו'. |
/vendor/overlay(/. * ) | vendor_overlay_file | system_server , zygote , idmap וכו'. |
כתוצאה מכך, יש לפעול לפי כללים ספציפיים (לאכוף באמצעות neverallows
) בעת תיוג קבצים נוספים במחיצת vendor
:
-
vendor_file
חייבת להיות תווית ברירת המחדל עבור כל הקבצים במחיצתvendor
. מדיניות הפלטפורמה מחייבת זאת כדי לגשת למימושי HAL מעבר. - כל
exec_types
החדשים שנוספו במחיצתvendor
דרך הספק SEPolicy חייבים להיות בעלי תכונהvendor_file_type
. זה נאכף באמצעות neverallows. - כדי למנוע התנגשויות עם עדכוני פלטפורמה/מסגרת עתידיים, הימנע מתיוג קבצים שאינם
exec_types
במחיצתvendor
. - כל התלות בספרייה עבור HAL של אותו תהליך המזוהה עם AOSP חייבות להיות מתויגות בתור
same_process_hal_file.
Procfs (/proc)
ניתן לתייג קבצים ב- /proc
באמצעות התווית genfscon
בלבד. באנדרואיד 7.0, מדיניות הפלטפורמה והספק השתמשו genfscon
כדי לתייג קבצים ב- procfs
.
המלצה: רק תוויות מדיניות פלטפורמה /proc
. אם תהליכי vendor
זקוקים לגישה לקבצים ב- /proc
המסומנים כעת עם תווית ברירת המחדל ( proc
), מדיניות הספק לא צריכה לתייג אותם במפורש ובמקום זאת צריכה להשתמש בסוג proc
הגנרי כדי להוסיף כללים עבור דומיינים של ספקים. זה מאפשר לעדכוני הפלטפורמה להתאים לממשקי ליבה עתידיים שנחשפו באמצעות procfs
ולתייג אותם באופן מפורש לפי הצורך.
Debugfs (/sys/kernel/debug)
ניתן לתייג file_contexts
Debugfs
ב- genfscon
. באנדרואיד 7.0 עד אנדרואיד 10, גם פלטפורמה וגם תווית ספק debugfs
.
ב-Android 11, לא ניתן לגשת debugfs
או להרכיב אותם במכשירי ייצור. יצרני התקנים צריכים להסיר debugfs
.
Tracefs (/sys/kernel/debug/tracing)
Tracefs
ניתן לתייג גם ב- file_contexts
וגם ב- genfscon
. באנדרואיד 7.0, רק הפלטפורמה מסמנת את התוויות של tracefs
.
המלצה: רק פלטפורמה רשאית לתייג tracefs
.
Sysfs (/sys)
קבצים ב- /sys
עשויים להיות מתויגים גם באמצעות file_contexts
וגם באמצעות genfscon
. באנדרואיד 7.0, גם הפלטפורמה וגם הספק משתמשים ב- file_contexts
וב- genfscon
כדי לתייג קבצים ב- sysfs
.
המלצה: הפלטפורמה עשויה לתייג צמתי sysfs
שאינם ספציפיים למכשיר. אחרת, רק הספק רשאי לתייג קבצים.
tmpfs (/dev)
קבצים ב- /dev
עשויים להיות מסומנים בתווית file_contexts
. באנדרואיד 7.0, קבצי תוויות של פלטפורמה וספקים כאן.
המלצה: הספק רשאי לתייג רק קבצים ב- /dev/vendor
(למשל, /dev/vendor/foo
, /dev/vendor/socket/bar
).
שורשים (/)
קבצים ב /
עשויים להיות מתויגים ב- file_contexts
. באנדרואיד 7.0, קבצי תוויות של פלטפורמה וספקים כאן.
המלצה: רק המערכת רשאית לתייג קבצים ב- /
.
נתונים (/data)
נתונים מסומנים באמצעות שילוב של file_contexts
ו- seapp_contexts
.
המלצה: לא לאפשר תיוג ספקים מחוץ ל- /data/vendor
. רק הפלטפורמה רשאית לתייג חלקים אחרים של /data
.
תכונות תאימות
מדיניות SELinux היא אינטראקציה בין סוגי מקור ויעד עבור מחלקות והרשאות אובייקט ספציפיות. לכל אובייקט (תהליכים, קבצים וכו') המושפע ממדיניות SELinux עשוי להיות רק סוג אחד, אך לסוג זה עשויות להיות מספר תכונות.
המדיניות נכתבת בעיקר במונחים של סוגים קיימים:
allow source_type target_type:target_class permission(s);
זה עובד מכיוון שהפוליסה נכתבה עם ידע מכל הסוגים. עם זאת, אם מדיניות הספק ומדיניות הפלטפורמה משתמשות בסוגים ספציפיים, והתווית של אובייקט ספציפי משתנה רק באחד מאותם מדיניות, האחרת עשויה להכיל מדיניות שהושגה או איבדה גישה שקודם לכן הסתמכה עליה. לדוגמה:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
ניתן לשנות ל:
File_contexts: /sys/A u:object_r:sysfs_A:s0
למרות שמדיניות הספק תישאר זהה, ה- v_domain
יאבד גישה עקב היעדר מדיניות עבור סוג sysfs_A
החדש.
על ידי הגדרת מדיניות במונחים של תכונות, נוכל לתת לאובייקט הבסיסי סוג שיש לו תכונה המתאימה למדיניות הן עבור הפלטפורמה והן עבור קוד הספק. ניתן לעשות זאת עבור כל הסוגים כדי ליצור ביעילות מדיניות תכונה שבה לא נעשה שימוש בסוגי קונקרטיים. בפועל, זה נדרש רק עבור חלקי הפוליסה החופפים בין הפלטפורמה לספק, המוגדרים ומסופקים כמדיניות ציבורית של פלטפורמה שנבנית כחלק ממדיניות הספק.
הגדרת מדיניות ציבורית כתכונות מנוסחות עומדת בשתי יעדי תאימות למדיניות:
- ודא שקוד הספק ממשיך לעבוד לאחר עדכון הפלטפורמה . מושגת על ידי הוספת תכונות לסוגים קונקרטיים עבור אובייקטים התואמים לאלה שעליהם נשען קוד הספק, תוך שמירה על גישה.
- יכולת לבטל פוליסה . מושגת על ידי תיחום ברור של ערכי מדיניות למאפיינים שניתן להסיר ברגע שהגרסה שאליה הם תואמים כבר לא נתמכת. הפיתוח יכול להמשיך בפלטפורמה, בידיעה שהמדיניות הישנה עדיין קיימת במדיניות הספקים והיא תוסר אוטומטית כאשר/אם היא תשתדרג.
יכולת כתיבה של מדיניות
כדי לעמוד ביעד לא לדרוש ידע על שינויי גרסאות ספציפיים לפיתוח מדיניות, אנדרואיד 8.0 כולל מיפוי בין סוגי מדיניות ציבורית של פלטפורמה והתכונות שלהם. סוג foo
ממופה לתכונה foo_v N
, כאשר N
היא הגרסה הממוקדת. vN
מתאים למשתנה הבנייה PLATFORM_SEPOLICY_VERSION
והוא בצורת MM.NN
, כאשר MM
מתאים למספר ה-SDK של הפלטפורמה ו- NN
היא גרסה ספציפית למדיניות פלטפורמה.
תכונות במדיניות ציבורית אינן מנוסחות, אלא קיימות כ-API שעליו ניתן לבנות מדיניות של פלטפורמה וספק כדי לשמור על יציבות הממשק בין שתי המחיצות. כותבי מדיניות הפלטפורמה והספקים יכולים להמשיך לכתוב מדיניות כפי שהיא כתובה היום.
מדיניות ציבורית של פלטפורמה מיוצאת כ- allow source_foo target_bar: class perm ;
נכלל כחלק ממדיניות הספקים. במהלך הקומפילציה (הכוללת את הגרסה המתאימה) היא עוברת טרנספורמציה למדיניות שתעבור לחלק הספק של המכשיר (מוצג בשפת הביניים המשותפת שהשתנתה (CIL)):
(allow source_foo_vN target_bar_vN (class (perm)))
מכיוון שמדיניות הספקים לעולם אינה מקדימה את הפלטפורמה, היא לא צריכה לדאוג לגרסאות קודמות. עם זאת, מדיניות הפלטפורמה תצטרך לדעת עד כמה רחוקה מדיניות הספקים, לכלול תכונות לסוגיה ולהגדיר מדיניות התואמת למאפיינים עם גרסאות.
הבדלי מדיניות
יצירה אוטומטית של תכונות על ידי הוספת _v N
לסוף כל סוג לא עושה כלום בלי מיפוי של תכונות לסוגים על פני הבדלי גרסאות. אנדרואיד מקיימת מיפוי בין גרסאות עבור תכונות ומיפוי של סוגים לתכונות אלו. זה נעשה בקובצי המיפוי שהוזכרו לעיל עם הצהרות, כגון (CIL):
(typeattributeset foo_vN (foo))
שדרוגי פלטפורמה
הסעיף הבא מפרט תרחישים עבור שדרוגי פלטפורמה.
אותם סוגים
תרחיש זה מתרחש כאשר אובייקט אינו משנה תוויות בגרסאות מדיניות. זה זהה לסוגי מקור ויעד וניתן לראות אותו עם /dev/binder
, שכותרתו binder_device
בכל הגרסאות. זה מיוצג במדיניות שעברה שינוי כ:
binder_device_v1 … binder_device_vN
בעת שדרוג מ- v1
→ v2
, מדיניות הפלטפורמה חייבת להכיל:
type binder_device; -> (type binder_device) (in CIL)
בקובץ המיפוי v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
בקובץ המיפוי v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
במדיניות הספק v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
במדיניות הספקים של v2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
סוגים חדשים
תרחיש זה מתרחש כאשר הפלטפורמה הוסיפה סוג חדש, מה שיכול לקרות בעת הוספת תכונות חדשות או במהלך הקשחת מדיניות.
- תכונה חדשה . כאשר הסוג מסמן אובייקט שלא היה קיים בעבר (כגון תהליך שירות חדש), קוד הספק לא קיים עמו בעבר אינטראקציה ישירה ולכן לא קיימת מדיניות מתאימה. לתכונה החדשה המתאימה לסוג אין תכונה בגרסה הקודמת, ולכן לא תצטרך ערך בקובץ המיפוי המכוון לגרסה זו.
- הקשחת מדיניות . כאשר הסוג מייצג הקשחת מדיניות, תכונת הסוג החדשה חייבת לקשר חזרה לשרשרת של תכונות התואמת לקודמתה (בדומה לדוגמה הקודמת המשנה
/sys/A
מ-sysfs
ל-sysfs_A
). קוד הספק מסתמך על כלל המאפשר גישה ל-sysfs
, וצריך לכלול את הכלל הזה כתכונה מהסוג החדש.
בעת שדרוג מ- v1
→ v2
, מדיניות הפלטפורמה חייבת להכיל:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
בקובץ המיפוי v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
בקובץ המיפוי v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
במדיניות הספק v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
במדיניות הספקים של v2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
הוסרו סוגים
תרחיש (נדיר) זה מתרחש כאשר סוג מוסר, מה שיכול לקרות כאשר האובייקט הבסיסי:
- נשאר אבל מקבל תווית אחרת.
- מוסר על ידי הפלטפורמה.
במהלך התרופפות המדיניות, סוג מוסר והאובייקט המסומן בסוג זה מקבל תווית אחרת שכבר קיימת. זה מייצג מיזוג של מיפוי תכונות: קוד הספק עדיין חייב להיות מסוגל לגשת לאובייקט הבסיסי באמצעות התכונה שהייתה לו בעבר, אך שאר המערכת חייבת כעת להיות מסוגלת לגשת אליו עם התכונה החדשה שלה.
אם התכונה שאליה הוחלף היא חדשה, התיוג מחדש זהה למקרה של הסוג החדש, אלא שכאשר נעשה שימוש בתווית קיימת, הוספה של התכונה הישנה סוג חדש תגרום לאובייקטים אחרים המסומנים גם הם בסוג זה להיות נגיש חדש. זה בעצם מה שנעשה על ידי הפלטפורמה ונחשב כפשרה מקובלת כדי לשמור על תאימות.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
גרסה 1 לדוגמה: סוגי כיווץ (הסרת sysfs_A)
בעת שדרוג מ- v1
→ v2
, מדיניות הפלטפורמה חייבת להכיל:
type sysfs; (type sysfs) (in CIL)
בקובץ המיפוי v1 (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
בקובץ המיפוי v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
במדיניות הספק v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
במדיניות הספקים של v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
דוגמה גרסה 2: הסרה מלאה (סוג foo)
בעת שדרוג מ- v1
→ v2
, מדיניות הפלטפורמה חייבת להכיל:
# nothing - we got rid of the type
בקובץ המיפוי v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
בקובץ המיפוי v2 (CIL):
# nothing - get rid of it
במדיניות הספק v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
במדיניות הספקים של v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
כיתה/הרשאות חדשות
תרחיש זה מתרחש כאשר שדרוג פלטפורמה מציג רכיבי מדיניות חדשים שאינם קיימים בגרסאות קודמות. לדוגמה, כאשר אנדרואיד הוסיפה את מנהל האובייקטים של servicemanager
שיצר את הרשאות ההוספה, האיתור והרשימה, דמונים של ספקים שרצו להירשם במנהל servicemanager
נזקקו להרשאות שלא היו זמינות. באנדרואיד 8.0, רק מדיניות הפלטפורמה עשויה להוסיף כיתות והרשאות חדשות.
כדי לאפשר לכל הדומיינים שהיו יכולים להיווצר או להרחיב על ידי מדיניות הספק להשתמש במחלקה החדשה ללא הפרעה, מדיניות הפלטפורמה צריכה לכלול כלל דומה ל:
allow {domain -coredomain} *:new_class perm;
זה עשוי אפילו לדרוש מדיניות המאפשרת גישה לכל סוגי הממשק (מדיניות ציבורית), כדי לוודא שתמונת הספק תקבל גישה. אם זה יגרום למדיניות אבטחה לא מקובלת (כפי שעשויה להיות עם השינויים במנהל השירות), ייתכן שדרוג ספק ייאלץ.
הוסר מחלקה/הרשאות
תרחיש זה מתרחש כאשר מנהל אובייקטים מוסר (כגון מנהל האובייקטים ZygoteConnection
) ואינו אמור לגרום לבעיות. המחלקה וההרשאות של מנהל האובייקטים יכולות להישאר מוגדרות במדיניות עד שגרסת הספק לא תשתמש בה עוד. זה נעשה על ידי הוספת ההגדרות לקובץ המיפוי המתאים.
התאמה אישית של ספקים לסוגים חדשים/מתויגים מחדש
סוגי ספקים חדשים נמצאים בליבה של פיתוח מדיניות ספקים שכן הם נחוצים לתיאור תהליכים חדשים, קבצים בינאריים, התקנים, תת-מערכות ונתונים מאוחסנים. ככזה, הכרחי לאפשר יצירת סוגים המוגדרים על ידי ספק.
מכיוון שמדיניות הספקים היא תמיד הישנה ביותר במכשיר, אין צורך להמיר אוטומטית את כל סוגי הספקים למאפיינים במדיניות. הפלטפורמה אינה מסתמכת על שום דבר מסומן במדיניות הספקים מכיוון שלפלטפורמה אין ידע על כך; עם זאת, הפלטפורמה תספק את התכונות והסוגים הציבוריים שבהם היא משתמשת כדי ליצור אינטראקציה עם אובייקטים המסומנים עם סוגים אלה (כגון domain
, sysfs_type
וכו'). כדי שהפלטפורמה תמשיך לקיים אינטראקציה נכונה עם אובייקטים אלה, יש ליישם את התכונות והסוגים כראוי וייתכן שיהיה צורך להוסיף כללים ספציפיים לדומיינים הניתנים להתאמה אישית (כגון init
).
שינויים בתכונה עבור אנדרואיד 9
מכשירים שמשדרגים לאנדרואיד 9 יכולים להשתמש בתכונות הבאות, אך אסור למכשירים המופעלים עם אנדרואיד 9.
תכונות המפרים
אנדרואיד 9 כולל את המאפיינים האלה הקשורים לתחום:
-
data_between_core_and_vendor_violators
. תכונה לכל הדומיינים שמפרים את הדרישה לא לשתף קבצים לפי נתיב ביןvendor
coredomains
. תהליכים של פלטפורמה וספק לא צריכים להשתמש בקבצים בדיסק כדי לתקשר (ABI לא יציב). המלצה:- קוד הספק צריך להשתמש ב-
/data/vendor
. - המערכת לא צריכה להשתמש ב-
/data/vendor
.
- קוד הספק צריך להשתמש ב-
-
system_executes_vendor_violators
. תכונה עבור כל תחומי המערכת (פרט ל-init
ו-shell domains
) שמפרים את הדרישה של אי ביצוע קבצים בינאריים של ספקים. לביצוע של קבצים בינאריים של ספקים יש API לא יציב. פלטפורמה לא אמורה להפעיל בינאריים של ספקים ישירות. המלצה:- תלות כזו של פלטפורמה בקבצים בינאריים של ספקים חייבת להיות מאחורי HIDL HALs.
אוֹ
- יש
coredomains
שזקוקים לגישה לקוביות בינאריות של ספקים למחיצת הספק ובכך להפסיק להיותcoredomain
.
- תלות כזו של פלטפורמה בקבצים בינאריים של ספקים חייבת להיות מאחורי HIDL HALs.
תכונות לא מהימנות
לאפליקציות לא מהימנות המארחות קוד שרירותי לא אמורה להיות גישה לשירותי HwBinder, למעט אלה הנחשבים בטוחים מספיק לגישה מאפליקציות כאלה (ראה שירותים בטוחים להלן). שתי הסיבות העיקריות לכך הן:
- שרתי HwBinder אינם מבצעים אימות לקוח מכיוון ש-HIDL אינו חושף כעת מידע UID של המתקשר. גם אם HIDL אכן חשפה נתונים כאלה, שירותי HwBinder רבים פועלים ברמה מתחת לזו של אפליקציות (כגון, HALs) או שאסור להסתמך על זהות האפליקציה לצורך הרשאה. לפיכך, ליתר ביטחון, הנחת ברירת המחדל היא שכל שירות של HwBinder מתייחס לכל לקוחותיו כבעלי אישור שווה לבצע פעולות המוצעות על ידי השירות.
- שרתי HAL (תת-קבוצה של שירותי HwBinder) מכילים קוד עם שיעור שכיחות גבוה יותר של בעיות אבטחה מאשר רכיבי
system/core
ויש להם גישה לשכבות התחתונות של המחסנית (כל הדרך עד לחומרה) ובכך מגדילות את ההזדמנויות לעקוף את מודל האבטחה של אנדרואיד .
שירותים בטוחים
שירותי כספת כוללים:
-
same_process_hwservice
. שירותים אלו (בהגדרה) פועלים בתהליך של הלקוח ובכך יש להם גישה זהה לתחום הלקוח בו מתנהל התהליך. -
coredomain_hwservice
. שירותים אלה אינם מהווים סיכונים הקשורים לסיבה מס' 2. -
hal_configstore_ISurfaceFlingerConfigs
. שירות זה תוכנן במיוחד לשימוש בכל תחום. -
hal_graphics_allocator_hwservice
. פעולות אלה מוצעות גם על ידי שירותsurfaceflinger
Binder, שאליו אפליקציות מורשות לגשת. -
hal_omx_hwservice
. זוהי גרסת HwBinder של שירותmediacodec
Binder, שאליו אפליקציות מורשות לגשת. -
hal_codec2_hwservice
. זוהי גרסה חדשה יותר שלhal_omx_hwservice
.
תכונות שימושיות
לכל hwservices
שאינם נחשבים בטוחים יש את התכונה untrusted_app_visible_hwservice
. לשרתי HAL המתאימים יש את התכונה untrusted_app_visible_halserver
. אסור למכשירים המופעלים עם אנדרואיד 9 להשתמש באף אחד מהמאפיינים לא untrusted
.
המלצה:
- אפליקציות לא מהימנות צריכות במקום זאת לדבר עם שירות מערכת שמדבר עם הספק HIDL HAL. לדוגמה, אפליקציות יכולות לדבר עם
binderservicedomain
, ואז שרת המדיה (שהואbinderservicedomain
mediaserver
בתורו מדבר עםhal_graphics_allocator
.אוֹ
- אפליקציות הזקוקות לגישה ישירה ל-HAL של
vendor
צריכות להיות עם דומיין sepolicy משלהם המוגדר על ידי ספק.
בדיקות תכונות קובץ
אנדרואיד 9 כולל מבחני זמן בנייה המבטיחים שלכל הקבצים במיקומים ספציפיים יש את התכונות המתאימות (כגון, לכל הקבצים ב- sysfs
יש את תכונת sysfs_type
הנדרשת).
פלטפורמה-מדיניות ציבורית
מדיניות הפלטפורמה-ציבור היא הליבה של התאמה למודל ארכיטקטורת אנדרואיד 8.0 מבלי לשמור על האיחוד של מדיניות הפלטפורמה מ-v1 ו-v2. ספקים חשופים לקבוצת משנה של מדיניות פלטפורמה המכילה סוגים ומאפיינים ניתנים לשימוש וכללים על אותם סוגים ותכונות, אשר לאחר מכן הופכים לחלק ממדיניות הספקים (כלומר vendor_sepolicy.cil
).
סוגים וכללים מתורגמים אוטומטית במדיניות שנוצרה על ידי הספק ל- attribute_v N
כך שכל הסוגים המסופקים על ידי הפלטפורמה הם תכונות עם גרסאות (עם זאת, תכונות אינן מנוסחות). הפלטפורמה אחראית למיפוי הסוגים הקונקרטיים שהיא מספקת לתכונות המתאימות כדי להבטיח שמדיניות הספק ממשיכה לתפקד ושהכללים שסופקו עבור גרסה מסוימת כלולים. השילוב של מדיניות ציבורית של פלטפורמה ומדיניות ספקים עונה על מטרת מודל הארכיטקטורה של אנדרואיד 8.0 לאפשר בניית פלטפורמה וספק עצמאיים.
מיפוי לייחוס שרשראות
בעת שימוש בתכונות למיפוי לגרסאות מדיניות, סוג ממפה לתכונה או למאפיינים מרובים, ומבטיח שאובייקטים המסומנים בסוג נגישים באמצעות תכונות המתאימות לסוגים הקודמים שלהם.
שמירה על מטרה להסתיר מידע על גרסה מכותב המדיניות פירושה יצירה אוטומטית של התכונות המנוסות והקצאתן לסוגים המתאימים. במקרה הנפוץ של טיפוסים סטטיים, זה פשוט: type_foo
ממפה ל- type_foo_v1
.
עבור שינוי תווית אובייקט כגון sysfs
→ sysfs_A
או mediaserver
→ audioserver
, יצירת מיפוי זה אינה טריוויאלית (ומתוארת בדוגמאות לעיל). מנהלי מדיניות הפלטפורמה חייבים לקבוע כיצד ליצור את המיפוי בנקודות מעבר עבור אובייקטים, מה שדורש הבנת הקשר בין אובייקטים והתוויות שהוקצו להם וקביעה מתי זה מתרחש. לצורך תאימות לאחור, המורכבות הזו צריכה להיות מנוהלת בצד הפלטפורמה, שהיא המחיצה היחידה שעלולה להופיע.
גרסה למעלה
לשם הפשטות, פלטפורמת אנדרואיד משחררת גרסת sepolicy כאשר חותכים ענף מהדורה חדש. כפי שתואר לעיל, מספר הגרסה כלול ב- PLATFORM_SEPOLICY_VERSION
והוא בצורת MM.nn
, כאשר MM
מתאים לערך SDK ו- nn
הוא ערך פרטי המתוחזק ב- /platform/system/sepolicy.
לדוגמה, 19.0
עבור Kitkat, 21.0
עבור Lollipop, 22.0
עבור Lollipop-MR1 23.0
עבור Marshmallow, 24.0
עבור נוגט, 25.0
עבור Nougat-MR1, 26.0
עבור Oreo, 27.0
עבור Oreo-MR1 ו- 28.0
עבור Android תמיד מספרים שלמים. לדוגמה, אם חבטת MR לגירסאות מחייבת שינוי לא תואם ב- system/sepolicy/public
אך לא ב-API bump, גרסת ה-sepolicy יכולה להיות: vN.1
. הגרסה הקיימת בענף פיתוח היא 10000.0
לא ישתמשו בה במכשירי משלוח.
אנדרואיד עשויה להוציא משימוש את הגרסה הישנה ביותר בעת העלאה למעלה. לקבלת מידע לגבי מתי להוציא גרסה משימוש, אנדרואיד עשויה לאסוף את מספר המכשירים עם מדיניות ספקים שפועלת באותה גרסת אנדרואיד ועדיין מקבלים עדכוני פלטפורמה גדולים. אם המספר קטן מסף מסוים, גרסה זו תוצאה משימוש.
השפעת ביצועים של מספר תכונות
כפי שמתואר ב- https://github.com/SELinuxProject/cil/issues/9 , מספר רב של תכונות שהוקצו לסוג מביא לבעיות ביצועים במקרה של החמצת מטמון מדיניות.
זו אושרה כבעיה באנדרואיד, אז בוצעו שינויים באנדרואיד 8.0 כדי להסיר תכונות שנוספו למדיניות על ידי מהדר המדיניות, כמו גם כדי להסיר תכונות שאינן בשימוש. שינויים אלה פתרו רגרסיות ביצועים.
System_ext מדיניות ציבורית ומוצר ציבורית
החל מאנדרואיד 11, מחיצות system_ext ומחיצות המוצר רשאיות לייצא את הסוגים הציבוריים המיועדים להן למחיצת הספק. בדומה למדיניות ציבורית של הפלטפורמה, הספק משתמש בסוגים ובכללים המתורגמים אוטומטית לתכונות הגרסה, למשל מ- type
ל- type_ N
, כאשר N
היא הגרסה של הפלטפורמה שעל פיה בנויה מחיצת הספק.
כאשר מחיצות system_ext ומחיצות המוצר מבוססות על אותה גרסת פלטפורמה N
, מערכת ה-build מייצרת קובצי מיפוי בסיסיים ל- system_ext/etc/selinux/mapping/ N .cil
ו- product/etc/selinux/mapping/ N .cil
, המכילים זהות מיפויים type
type_ N
. הספק יכול לגשת type
עם התכונה type_ N
.
במקרה שרק מחיצות system_ext ומחיצות המוצר מתעדכנות, אמור N
ל- N+1
(או מאוחר יותר), בעוד הספק נשאר ב- N
, הספק עלול לאבד גישה לסוגי system_ext ומחיצות המוצר. כדי למנוע שבירה, מחיצות system_ext ומחיצות המוצר צריכות לספק קובצי מיפוי מסוגי בטון לתכונות type_ N
כל שותף אחראי לתחזוקת קובצי המיפוי, אם הם מתכוונים לתמוך בספק N
עם N+1
(או מאוחר יותר) system_ext ומחיצות מוצר.
לשם כך, השותפים צפויים:
- העתק את קובצי המיפוי הבסיסיים שנוצרו מ-
N
system_ext ומחיצות המוצר לעץ המקור שלהם. - שנה את קבצי המיפוי לפי הצורך.
- התקן את קובצי המיפוי ל-
N+1
(או מאוחר יותר) system_ext ומחיצות המוצר.
לדוגמה, נניח של- N
system_ext יש סוג ציבורי אחד בשם foo_type
. אז system_ext/etc/selinux/mapping/ N .cil
N .cil במחיצת N
system_ext ייראה כך:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
אם bar_type
מתווסף ל- N+1
bar_type
, ואם יש למפות את bar_type ל- foo_type
עבור ספק N
, ניתן לעדכן את N .cil
.cil מ-
(typeattributeset foo_type_N (foo_type))
ל
(typeattributeset foo_type_N (foo_type bar_type))
ולאחר מכן מותקן במחיצה של N+1
system_ext. ספק N
יכול להמשיך לגשת ל-foo_type ו- bar_type
של N+1
foo_type
.
תיוג הקשרי SELinux
כדי לתמוך בהבחנה בין פלטפורמה למדיניות של ספק, המערכת בונה קבצי הקשר של SELinux בצורה שונה כדי לשמור אותם נפרדים.
הקשרי קובץ
אנדרואיד 8.0 הציגה את השינויים הבאים עבור file_contexts
:
- כדי למנוע תקורה נוספת של קומפילציה במכשיר במהלך האתחול,
file_contexts
מפסיקים להתקיים בצורה הבינארית. במקום זאת, הם קריאים, קובץ טקסט של ביטוי רגולרי כגון{property, service}_contexts
(כפי שהיו לפני 7.0). - ה-
file_contexts
מחולקים בין שני קבצים:-
plat_file_contexts
- פלטפורמת אנדרואיד
file_context
שאין לה תוויות ספציפיות למכשיר, למעט תיוג חלקים של מחיצת/vendor
שחייבים להיות מתויגים במדויק כדי להבטיח תפקוד תקין של קבצי sepolicy. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/plat_file_contexts
במכשיר ולהיטען על ידיinit
בהתחלה יחד עם הספקfile_context
.
- פלטפורמת אנדרואיד
-
vendor_file_contexts
-
file_context
ספציפי למכשיר שנבנה על ידי שילוב שלfile_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - יש להתקין ב-
/vendor/etc/selinux/vendor_file_contexts
במחיצתvendor
ולהיטען על ידיinit
בהתחלה יחד עם הפלטפורמהfile_context
.
-
-
הקשרי נכס
באנדרואיד 8.0, ה- property_contexts
מפוצל בין שני קבצים:
-
plat_property_contexts
- פלטפורמת Android
property_context
שאין לה תוויות ספציפיות למכשיר. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/plat_property_contexts
על ידיinit
בהתחלה יחד עם הספקproperty_contexts
.
- פלטפורמת Android
-
vendor_property_contexts
-
property_context
ספציפי למכשיר שנבנה על ידי שילוב שלproperty_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - חייב להתגורר במחיצת
vendor
ב-/vendor/etc/selinux/vendor_property_contexts
על ידיinit
בהתחלה יחד עם הפלטפורמהproperty_context
-
הקשרי שירות
באנדרואיד 8.0, service_contexts
מפוצל בין הקבצים הבאים:
-
plat_service_contexts
-
service_context
ספציפי לפלטפורמת Android עבור מנהלservicemanager
. ל-service_context
אין תוויות ספציפיות למכשיר. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/plat_service_contexts
servicemanager
ידי Servicemanager בהתחלה יחד עם הספקservice_contexts
.
-
-
vendor_service_contexts
-
service_context
ספציפי למכשיר שנבנה על ידי שילובservice_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - חייב להתגורר במחיצת
vendor
ב-/vendor/etc/selinux/vendor_service_contexts
servicemanager
ידי Servicemanager בהתחלה יחד עם הפלטפורמהservice_contexts
. - למרות ש-
servicemanager
מחפש את הקובץ הזה בזמן האתחול, עבור התקןTREBLE
תואם לחלוטין, ה-vendor_service_contexts
אסור להתקיים. הסיבה לכך היא שכל אינטראקציה בין תהליכיvendor
system
חייבת לעבור דרךhwservicemanager
/hwbinder
.
-
-
plat_hwservice_contexts
- פלטפורמת אנדרואיד
hwservice_context
עבורhwservicemanager
שאין לה תוויות ספציפיות למכשיר. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/plat_hwservice_contexts
על ידיhwservicemanager
בהתחלה יחד עםvendor_hwservice_contexts
.
- פלטפורמת אנדרואיד
-
vendor_hwservice_contexts
-
hwservice_context
ספציפי למכשיר שנבנה על ידי שילוב שלhwservice_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - חייב להתגורר במחיצת
vendor
ב-/vendor/etc/selinux/vendor_hwservice_contexts
על ידיhwservicemanager
בהתחלה יחד עםplat_service_contexts
.
-
-
vndservice_contexts
-
service_context
ספציפי למכשיר עבורvndservicemanager
שנבנה על ידי שילובvndservice_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
ב-Boardconfig.mk
של המכשיר. - קובץ זה חייב להימצא במחיצת
vendor
בכתובת/vendor/etc/selinux/vndservice_contexts
על ידיvndservicemanager
בהתחלה.
-
הקשרים של Seapp
באנדרואיד 8.0, seapp_contexts
מפוצל בין שני קבצים:
-
plat_seapp_contexts
- פלטפורמת אנדרואיד
seapp_context
שאין בה שינויים ספציפיים למכשיר. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/plat_seapp_contexts.
- פלטפורמת אנדרואיד
-
vendor_seapp_contexts
- הרחבה ספציפית למכשיר לפלטפורמה
seapp_context
שנבנתה על ידי שילוב שלseapp_contexts
שנמצאו בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - חייב להתגורר במחיצת
vendor
ב-/vendor/etc/selinux/vendor_seapp_contexts
.
- הרחבה ספציפית למכשיר לפלטפורמה
הרשאות MAC
באנדרואיד 8.0, mac_permissions.xml
מחולק בין שני קבצים:
- פלטפורמה
mac_permissions.xml
- פלטפורמת אנדרואיד
mac_permissions.xml
שאין בה שינויים ספציפיים למכשיר. - חייב להתגורר במחיצת
system
ב-/system/etc/selinux/.
- פלטפורמת אנדרואיד
- ללא פלטפורמה
mac_permissions.xml
- הרחבה ספציפית למכשיר לפלטפורמה
mac_permissions.xml
שנבנתה מ-mac_permissions.xml
שנמצאת בספריות שעליהן הצביעBOARD_SEPOLICY_DIRS
בקבציBoardconfig.mk
של המכשיר. - חייב להתגורר במחיצת
vendor
ב-/vendor/etc/selinux/.
- הרחבה ספציפית למכשיר לפלטפורמה