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

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

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

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

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

חשוב גם לזכור לא:

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

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

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

  1. להשתמש בליבת Android העדכנית.
  2. שימוש בעיקרון של הרשאות מינימליות.
  3. יש לטפל רק בתוספות שלכם ל-Android. מדיניות ברירת המחדל פועלת באופן אוטומטי עם קוד המקור של Android Open Source Project.
  4. חלוקה של רכיבי התוכנה למחיצות (compartments) של מודולים שמבצעים משימות ספציפיות.
  5. יוצרים מדיניות SELinux שמבודדת את המשימות האלה מפונקציות לא קשורות.
  6. צריך להעביר את כללי המדיניות האלה לקובצי *.te (הסיומת של קובצי המקור של מדיניות SELinux) בספרייה /device/manufacturer/device-name/sepolicy, ולהשתמש במשתני BOARD_SEPOLICY כדי לכלול אותם ב-build.
  7. בשלב הראשון, כדאי להגדיר דומיינים חדשים כמתירניים. כדי לעשות זאת, צריך להשתמש בהצהרה מתירנית בקובץ .te של הדומיין.
  8. ניתוח התוצאות ושיפור הגדרות הדומיינים.
  9. מסירים את ההצהרה המאפשרת כשלא מופיעות דחיות נוספות ב-builds של 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 וגם מדיניות המוצרים מחולקות למדיניות ציבורית ולמדיניות פרטית, וספקים יכולים להשתמש במדיניות הציבורית של 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 ו-product של OEM. הכללים במדיניות האבטחה של הספק שמשתמשים במדיניות הציבורית של המוצר וב-system_ext של היצרן הופכים ל-NOP כי הגדרות הטיפוס הספציפיות ליצרן חסרות.
הערה: חשוב להיזהר במיוחד כשמשתמשים במדיניות הציבורית של 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 לדוגמה.

תוספי vendor-image שמספקים רכיבים מורחבים של 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 של מסגרת בלבד.