התאמה אישית של SELinux

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

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

כשמתחילים להתאים אישית את SELinux, חשוב לזכור:

  • כתיבת מדיניות SELinux לכל הדימונים החדשים
  • שימוש בדומיינים מוגדרים מראש לפי הצורך
  • הקצאת דומיין לכל תהליך שנוצר בתור שירות init
  • מומלץ להכיר את המאקרו לפני שכותבים את המדיניות
  • שליחת שינויים במדיניות הליבה ל-AOSP

וחשוב לזכור:

  • יצירת מדיניות לא תואמת
  • התאמה אישית של מדיניות משתמש הקצה
  • אישור להתאמה אישית של מדיניות MDM (ניהול מכשירים ניידים)
  • הפחדת משתמשים בגלל הפרות מדיניות
  • הוספת דלתות אחוריות

הדרישות הספציפיות מפורטות בקטע Kernel Security Features שבמסמך הגדרת התאימות ל-Android.

ב-SELinux נעשה שימוש בגישה לרשימת היתרים, כלומר כדי להעניק גישה, צריך לקבל כל גישה מפורשת במדיניות. מדיניות ברירת המחדל של SELinux ב-Android כבר תומכת ב-Android Open Source Project, כך שאין צורך לשנות את הגדרות SELinux בשום צורה. אם תבחרו להתאים אישית את ההגדרות של SELinux, חשוב מאוד לא לשבור אפליקציות קיימות. כדי להתחיל:

  1. שימוש בליבה (kernel) העדכנית של Android.
  2. שימוש בעיקרון של הרשאות מינימליות.
  3. יש לטפל רק בתוספים שלכם ל-Android. מדיניות ברירת המחדל פועלת באופן אוטומטי עם קוד המקור של Android Open Source Project.
  4. חלוקה של רכיבי התוכנה למודולים שמבצעים משימות ספציפיות.
  5. יוצרים מדיניות SELinux שמבודדת את המשימות האלה מפונקציות לא קשורות.
  6. צריך להעביר את כללי המדיניות האלה לקובצי *.te (הסיומת של קובצי המקור של מדיניות SELinux) בספרייה /device/manufacturer/device-name/sepolicy, ולהשתמש במשתני BOARD_SEPOLICY כדי לכלול אותם ב-build.
  7. בשלב הראשון, כדאי להגדיר דומיינים חדשים כמתירניים. כדי לעשות זאת, צריך להשתמש בהצהרה מתירנית בקובץ .te של הדומיין.
  8. ניתוח התוצאות וצמצום הגדרות הדומיין.
  9. מסירים את ההצהרה המאפשרת כשלא מופיעות דחיות נוספות בגרסאות build של userdebug.

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

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

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

הצהרות מדיניות לדוגמה

SELinux מבוסס על שפת המחשב M4, ולכן הוא תומך במגוון מאקרוים כדי לחסוך זמן.

בדוגמה הבאה, לכל הדומיינים ניתנת גישה לקריאה מ-/dev/null או לכתיבה ב-/dev/null ולקריאה מ-/dev/zero.

# Allow read / write access to /dev/null
allow domain null_device:chr_file { getattr open read ioctl lock append write};

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file { getattr open read ioctl lock };

אפשר לכתוב את אותה הצהרה באמצעות מאקרו *_file_perms של SELinux (קיצור דרך):

# Allow read / write access to /dev/null
allow domain null_device:chr_file rw_file_perms;

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file r_file_perms;

מדיניות לדוגמה

זוהי דוגמה מלאה למדיניות DHCP, שנסביר בהמשך:

type dhcp, domain;
permissive dhcp;
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;

init_daemon_domain(dhcp)
net_domain(dhcp)

allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service
};
allow dhcp self:packet_socket create_socket_perms;
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write };
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
# For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net:file write;
allow dhcp system_prop:property_service set ;
unix_socket_connect(dhcp, property, init)

type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;

allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };

נבחן את הדוגמה:

בשורה הראשונה, הצהרת הסוג, הדימון של DHCP יורש ממדיניות האבטחה הבסיסית (domain). לפי הדוגמאות הקודמות לביטויים, DHCP יכול לקרוא מ-/dev/null ולכתוב אליו.

בשורה השנייה, DHCP מזוהה כדומיין מותיר.

בשורה init_daemon_domain(dhcp), לפי המדיניות מצוין ש-DHCP מופץ מ-init ומותר לו לתקשר איתו.

בשורה net_domain(dhcp), המדיניות מאפשרת ל-DHCP להשתמש בפונקציות רשת נפוצות מהדומיין net, כמו קריאה וכתיבה של חבילות TCP, תקשורת דרך שקעים וביצוע בקשות DNS.

בשורה allow dhcp proc_net:file write;, המדיניות קובעת ש-DHCP יכול לכתוב לקבצים ספציפיים ב-/proc. השורה הזו מדגימה את התיוג המפורט של הקבצים ב-SELinux. הוא משתמש בתווית proc_net כדי להגביל את גישת הכתיבה רק לקבצים שנמצאים ב-/proc/sys/net.

הבלוק האחרון בדוגמה שמתחיל ב-allow dhcp netd:fd use; מציג את האופן שבו אפליקציות יכולות לבצע אינטראקציה זו עם זו. לפי המדיניות, DHCP ו-netd יכולים לתקשר ביניהם באמצעות מתארי קבצים, קובצי FIFO, שקעי נתונים ושקעי סטרימינג של UNIX. ‏DHCP יכול לקרוא ולכתוב רק בסוקטות של חבילות הנתונים ובסוקטות של תהליכי הזרמה ב-UNIX, אבל לא ליצור אותן או לפתוח אותן.

אמצעי הבקרה הזמינים

דרגה הרשאה
קובץ
ioctl read write create getattr setattr lock relabelfrom relabelto append
unlink link rename execute swapon quotaon mounton
ספרייה
add_name remove_name reparent search rmdir open audit_access execmod
שקע
ioctl read write create getattr setattr lock relabelfrom relabelto append bind
connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg
name_bind
מערכת קבצים
mount remount unmount getattr relabelfrom relabelto transition associate
quotamod quotaget
תהליך דיפוזיה הפוך
fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched
getsession getpgid setpgid getcap setcap share getattr setexec setfscreate
noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem
execstack execheap setkeycreate setsockcreate
אבטחה
compute_av compute_create compute_member check_context load_policy
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot
read_policy
יכולת
chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap
linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock
ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin
sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write
audit_control setfcap

עוד

ועוד

כללי neverallow

כללי neverallow של SELinux אוסרים התנהגות שלא אמורה להתרחש אף פעם. בעזרת בדיקות תאימות, כללי neverallow של SELinux נאכפים עכשיו בכל המכשירים.

ההנחיות הבאות נועדו לעזור ליצרנים להימנע משגיאות שקשורות לכללי neverallow במהלך ההתאמה האישית. מספרי הכללים שמופיעים כאן תואמים ל-Android 5.1 ועשויים להשתנות בהתאם לגרסה.

כלל 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
עיינו בדף הראשי של ptrace. היכולת sys_ptrace מאפשרת ptrace לכל תהליך, ומעניקה שליטה רבה על תהליכים אחרים. היא צריכה להיות שייכת רק לרכיבי מערכת ייעודיים שמפורטים בכלל. הצורך ביכולת הזו מצביע לעיתים קרובות על נוכחות של משהו שלא מיועד לגרסאות build שניתנות למשתמשים או לפונקציות שאינן נחוצות. מסירים את הרכיב הלא הכרחי.

כלל 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
הכלל הזה נועד למנוע את ההפעלה של קוד שרירותי במערכת. באופן ספציפי, הוא קובע שרק קוד ב-/system מופעל, וכך מאפשר להבטיח אבטחה באמצעות מנגנונים כמו הפעלה מאומתת. לרוב, הפתרון הטוב ביותר במקרה של בעיה בכלל neverallow הוא להעביר את הקוד הבעייתי למחיצה /system.

התאמה אישית של SEPolicy ב-Android מגרסה 8.0 ואילך

בקטע הזה מפורטות הנחיות למדיניות SELinux של ספקים ב-Android מגרסה 8.0 ואילך, כולל פרטים על SEPolicy של Android Open Source Project‏ (AOSP) ועל התוספים של SEPolicy. למידע נוסף על האופן שבו מדיניות SELinux נשמרת תואמת במחיצות ובגרסאות Android שונות, ראו תאימות.

מיקום המדיניות

בגרסאות Android 7.0 וגרסאות מוקדמות יותר, יצרני המכשירים יכלו להוסיף מדיניות ל-BOARD_SEPOLICY_DIRS, כולל מדיניות שנועדה להוסיף למדיניות AOSP בסוגים שונים של מכשירים. ב-Android מגרסה 8.0 ואילך, הוספת מדיניות ל-BOARD_SEPOLICY_DIRS תמקם את המדיניות רק בתמונת הספק.

ב-Android מגרסה 8.0 ואילך, המדיניות חלה במיקומים הבאים ב-AOSP:

  • system/sepolicy/public. כוללת מדיניות שמיוצאת לשימוש במדיניות ספציפית לספק. הכול עובר לתשתית התאימות של Android 8.0. המדיניות הציבורית אמורה להישאר קבועה במהלך הגרסאות, כך שתוכלו לכלול כל דבר /public במדיניות בהתאמה אישית. לכן, סוג המדיניות שאפשר להציב ב-/public מוגבל יותר. אפשר להתייחס אליו כאל ה-API של מדיניות הפלטפורמה המיוצאת: כל מה שקשור לממשק בין /system לבין /vendor שייך לכאן.
  • system/sepolicy/private כוללת מדיניות שנדרשת לתפקוד של קובץ האימג' של המערכת, אבל מדיניות קובץ האימג' של הספק לא אמורה לדעת עליה.
  • system/sepolicy/vendor. כולל מדיניות לרכיבים שמופיעים ב-/vendor אבל נמצאים בעץ הליבה של הפלטפורמה (לא בספריות ספציפיות למכשיר). זהו תוצר של ההבחנה של מערכת ה-build בין מכשירים לבין רכיבים גלובליים. מבחינה מושגית, זהו חלק מהמדיניות הספציפית למכשיר שמתוארת בהמשך.
  • device/manufacturer/device-name/sepolicy. כולל מדיניות ספציפית למכשיר. הוא כולל גם התאמות של המכשיר למדיניות, שב-Android 8.0 ואילך תואמות למדיניות של הרכיבים בתמונת הספק.

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

  • SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS. כולל מדיניות שיוצאו לשימוש במדיניות ספציפית לספק. מותקן במחיצה system_ext.
  • SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS. כולל מדיניות שנדרשת לתפקוד של קובץ האימג' system_ext, אבל מדיניות קובץ האימג' של הספק לא אמורה לדעת עליה. מותקן במחיצה system_ext.
  • PRODUCT_PUBLIC_SEPOLICY_DIRS. כולל מדיניות שמיוצאת לשימוש במדיניות ספציפית לספק. מותקן במחיצה של המוצר.
  • PRODUCT_PRIVATE_SEPOLICY_DIRS. כוללת מדיניות שנדרשת לתפקוד של תמונת המוצר, אבל לא ידוע על מדיניות הספק לגבי תמונות. מותקן במחיצה של המוצר.
הערה: כשמשתמשים ב-GSI, המחיצות system_ext ומחיצות המוצר של OEM לא מותקנות. הכללים במדיניות בנושא ספק לפי מדיניות system_ext ובמדיניות הציבורית לגבי מוצר של ה-OEM הופכים ל-NOP כי חסרות הגדרות לגבי סוגים ספציפיים ל-OEM.
הערה: חשוב להיזהר במיוחד כשמשתמשים במדיניות הציבורית של system_ext ובמדיניות הציבורית של המוצר. כללי המדיניות הציבורית פועלים כ-API מיוצא בין system_ext/product לבין הספק. השותפים אמורים לנהל את בעיות התאימות בעצמם.

תרחישי מדיניות נתמכים

במכשירים שיושקו עם Android מגרסה 8.0 ואילך, קובץ האימג' של הספק צריך לפעול עם קובץ האימג' של מערכת ההפעלה של יצרן הציוד המקורי (OEM) ועם קובץ האימג' של מערכת ההפעלה AOSP לדוגמה ש-Google מספקת (ולעבור את בדיקת CTS בקובץ האימג' לדוגמה הזה). הדרישות האלה מבטיחות הפרדה ברורה בין המסגרת לבין קוד הספק. מכשירים כאלה תומכים בתרחישים הבאים.

תוספי vendor-image-only

דוגמה: הוספת שירות חדש ל-vndservicemanager מתוך קובץ האימג' של הספק שתומך בתהליכים מקובץ האימג' של הספק.

כמו במכשירים שהושקעו עם גרסאות קודמות של Android, מוסיפים התאמה אישית ספציפית למכשיר בקובץ device/manufacturer/device-name/sepolicy. המדיניות החדשה בנוגע לאופן האינטראקציה של רכיבי הספק עם רכיבים אחרים של אותו ספק (בלבד) צריכה לכלול סוגים שנמצאים רק ב-device/manufacturer/device-name/sepolicy. המדיניות שמופיעה כאן מאפשרת לקוד של הספק לפעול, לא תתעדכן כחלק מעדכון OTA של מסגרת בלבד, ומופיעה במדיניות המשולבת במכשיר עם קובץ האימג' של מערכת AOSP לדוגמה.

תמיכה בתמונות של ספקים לעבודה עם AOSP

דוגמה: הוספת תהליך חדש (שנרשם באמצעות hwservicemanager בתמונת הספק) שמטמיע HAL שמוגדר על ידי AOSP.

כמו במכשירים שהושקעו עם גרסאות קודמות של Android, מבצעים התאמה אישית ספציפית למכשיר בקובץ device/manufacturer/device-name/sepolicy. המדיניות שמיוצאת כחלק מ-system/sepolicy/public/ זמינה לשימוש, והיא נשלחת כחלק ממדיניות הספק. אפשר להשתמש בסוגי המאפיינים ובמאפיינים מהמדיניות הציבורית בכללים חדשים שמכתיבים אינטראקציות עם הביטים החדשים הספציפיים לספק, בכפוף למגבלות neverallow שצוינו. בדומה למקרה של הספק בלבד, המדיניות החדשה לא תתעדכן כחלק מעדכון OTA של מסגרת בלבד, והיא תופיע במדיניות המשולבת במכשיר עם קובץ האימג' של מערכת AOSP לדוגמה.

תוספים של תמונות מערכת בלבד

דוגמה: הוספת שירות חדש (שנרשם ב-servicemanager) שרק תהליכים אחרים מתוך קובץ האימג' של המערכת יכולים לגשת אליו.

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

תוספי תמונות של ספק שמציגים רכיבי AOSP מורחבים

דוגמה: HAL חדש שאינו AOSP לשימוש בלקוחות מורחבים שקיימים גם בתמונת המערכת של AOSP (כמו system_server מורחב).

המדיניות של האינטראקציה בין המערכת לספק חייבת להיכלל בספרייה device/manufacturer/device-name/sepolicy שנשלחת במחיצה של הספק. התרחיש הזה דומה לתרחיש שלמעלה, שבו מוסיפים תמיכה בתמונה של הספק כדי שתעבוד עם קובץ האימג' של AOSP לדוגמה, אלא שבמקרה הזה יכול להיות שרכיבי AOSP ששונו יצטרכו גם מדיניות נוספת כדי לפעול כראוי עם שאר המחיצה של המערכת (זה בסדר כל עוד עדיין יש להם תוויות של סוג AOSP ציבורי).

המדיניות בנושא אינטראקציה בין רכיבים ציבוריים של AOSP לבין תוספים לתמונה המערכתית בלבד צריכה להיות ב-system/sepolicy/private.

תוספים של קובצי אימג' למערכת עם גישה רק לממשקי AOSP

דוגמה: תהליך מערכת חדש שאינו AOSP צריך לגשת ל-HAL שעליו AOSP מסתמך.

המצב הזה דומה לדוגמה להרחבה מסוג system-image-only, אלא שרכיבי מערכת חדשים יכולים לקיים אינטראקציה דרך הממשק system/vendor. המדיניות של רכיב המערכת החדש צריכה להיכלל ב-system/sepolicy/private, וזה מקובל בתנאי שהיא עוברת דרך ממשק שכבר הוגדר על ידי AOSP ב-system/sepolicy/public (כלומר, הסוגי והמאפיינים הנדרשים לפונקציונליות נמצאים שם). אפשר לכלול מדיניות במדיניות הספציפית למכשיר, אבל לא תהיה אפשרות להשתמש בסוגי system/sepolicy/private אחרים או לשנות אותה (בכל דרך שמשפיעה על המדיניות) כתוצאה מעדכון של המסגרת בלבד. אפשר לשנות את המדיניות בעדכון OTA של מסגרת בלבד, אבל היא לא תופיע כשמשתמשים בתמונת מערכת של AOSP (שבה גם לא יהיה רכיב המערכת החדש).

תוספים של תמונות של ספקים שמוצגים בהם רכיבי מערכת חדשים

דוגמה: הוספת HAL חדש שאינו AOSP לשימוש בתהליך לקוח ללא אנלוגי AOSP (ולכן נדרש לו דומיין משלו).

בדומה לדוגמה של AOSP-extensions, המדיניות של האינטראקציות בין המערכת לספק חייבת להימצא בספרייה device/manufacturer/device-name/sepolicy שנשלחת במחיצה של הספק (כדי לוודא שלמדיניות המערכת אין גישה לפרטים ספציפיים לספק). אפשר להוסיף סוגים ציבוריים חדשים שמרחיבים את המדיניות בקובץ system/sepolicy/public. צריך לעשות זאת רק בנוסף למדיניות הקיימת של AOSP, כלומר, לא להסיר את המדיניות הציבורית של AOSP. לאחר מכן תוכלו להשתמש בסוגי הרשאות הגישה הציבוריים החדשים במדיניות ב-system/sepolicy/private וב-device/manufacturer/device-name/sepolicy.

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

תרחישים של מדיניות שלא נתמכים

מכשירים שהושקעו עם Android 8.0 ואילך לא תומכים בתרחיש המדיניות ובדוגמאות הבאות.

תוספים נוספים לתמונת המערכת שצריכים הרשאה לרכיבי תמונת ספק חדשים אחרי OTA של מסגרת בלבד

דוגמה: תהליך מערכת חדש שאינו AOSP, שדורש דומיין משלו, יתווסף במהדורת Android הבאה ויידרש לו גישה ל-HAL חדש שאינו AOSP.

בדומה לאינטראקציה של רכיבי מערכת ורכיבי ספקים חדשים (לא AOSP), אלא שסוג המערכת החדש מוצג בעדכון OTA של מסגרת בלבד. אפשר להוסיף את הסוג החדש למדיניות ב-system/sepolicy/public, אבל למדיניות הספק הקיימת לא ידוע על הסוג החדש, כי היא עוקבת רק אחרי המדיניות הציבורית של מערכת Android 8.0. ב-AOSP פותרים את הבעיה הזו על ידי חשיפת משאבים שסופקו על ידי הספק באמצעות מאפיין (לדוגמה, המאפיין hal_foo), אבל מאחר ש-system/sepolicy/public לא תומך בתוספים של שותפי מאפיינים, השיטה הזו לא זמינה למדיניות של הספק. צריכה להיות גישה מסוג ציבורי שכבר היה קיים.

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

המדיניות על תמונת המערכת צריכה להיכתב ללא ידע לגבי התאמות אישיות ספציפיות של ספק. כך, המדיניות לגבי ממשקים ספציפיים ב-AOSP נחשפת באמצעות מאפיינים ב-system/sepolicy/public, כדי שמדיניות הספקים תוכל להביע הסכמה למדיניות מערכת עתידית שתשתמש במאפיינים האלה. עם זאת, אין תמיכה בתוספים של מאפיינים ב-system/sepolicy/public, ולכן כל המדיניות שקובעת איך רכיבי המערכת מקיימים אינטראקציה עם רכיבים חדשים של ספקים (שאינם מטופלים על ידי מאפיינים שכבר קיימים ב-AOSP system/sepolicy/public) חייבת להיות ב-device/manufacturer/device-name/sepolicy. המשמעות היא שסוגי מערכות לא יכולים לשנות את הגישה שמותר לספקים מסוגים שונים לקבל כחלק מעדכון OTA של מסגרת בלבד.