אנדרואיד מעודדת בחום יצרני OEM לבדוק את יישומי ה-SELinux שלהם ביסודיות. כאשר היצרנים מיישמים את SELinux, עליהם להחיל תחילה את המדיניות החדשה על מאגר בדיקות של מכשירים.
לאחר החלת מדיניות חדשה, ודא ש-SELinux פועל במצב הנכון במכשיר על ידי הנפקת הפקודה getenforce
.
זה מדפיס את מצב ה-SELinux העולמי: או אכיפה או מתירנית. כדי לקבוע את מצב ה-SELinux עבור כל תחום, עליך לבחון את הקבצים המתאימים או להפעיל את הגרסה העדכנית ביותר של sepolicy-analyze
עם הדגל המתאים ( -p
), הקיים ב- /platform/system/sepolicy/tools/
.
קריאת הכחשות
בדוק אם יש שגיאות, המנותבות כיומני אירועים ל- dmesg
ו- logcat
וניתנות לצפייה מקומית במכשיר. על היצרנים לבחון את הפלט של SELinux ל- dmesg
במכשירים אלה ולחדד את ההגדרות לפני שחרור פומבי במצב מתירני ובסופו של דבר לעבור למצב אכיפה. הודעות יומן SELinux מכילות avc:
ולכן ניתן למצוא אותן בקלות עם grep
. אפשר ללכוד את יומני ההכחשה המתמשכים על ידי הפעלת cat /proc/kmsg
או ללכוד יומני הכחשה מהאתחול הקודם על ידי הפעלת cat /sys/fs/pstore/console-ramoops
.
הודעות השגיאה של SELinux מוגבלות בקצב לאחר השלמת האתחול כדי להימנע מהשחתת היומנים. כדי לוודא שאתה רואה את כל ההודעות הרלוונטיות תוכל להשבית זאת על ידי הפעלת adb shell auditctl -r 0
.
עם פלט זה, היצרנים יכולים לזהות בקלות מתי משתמשי מערכת או רכיבים מפרים את מדיניות SELinux. לאחר מכן, יצרנים יכולים לתקן את ההתנהגות הגרועה הזו, או על ידי שינויים בתוכנה, מדיניות SELinux או שניהם.
באופן ספציפי, הודעות יומן אלה מציינות אילו תהליכים ייכשלו במצב אכיפה ומדוע. הנה דוגמא:
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
תפרש את הפלט הזה כך:
- ה-
{ connectto }
למעלה מייצג את הפעולה הננקטת. יחד עם ה-tclass
בסוף (unix_stream_socket
), הוא אומר לך בערך מה נעשה במה. במקרה זה, משהו ניסה להתחבר לשקע זרם יוניקס. -
scontext (u:r:shell:s0)
אומר לך איזה הקשר יזם את הפעולה. במקרה הזה זה משהו שפועל כקליפה. - ה-
tcontext (u:r:netd:s0)
אומר לך את ההקשר של יעד הפעולה. במקרה זה, זה unix_stream_socket בבעלותnetd
. - ה-
comm="ping"
בחלק העליון נותן לך רמז נוסף לגבי מה שהופעל בזמן שההכחשה נוצרה. במקרה הזה, זה רמז די טוב.
דוגמה אחרת:
adb shell su root dmesg | grep 'avc: '
תְפוּקָה:
<5> type=1400 audit: avc: denied { read write } for pid=177 comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 tcontext=u:object_r:kmem_device:s0 tclass=chr_file
להלן מרכיבי המפתח מהכחשה זו:
- פעולה - ניסיון הפעולה מודגש בסוגריים,
read write
אוsetenforce
. - Actor - הערך
scontext
(הקשר מקור) מייצג את השחקן, במקרה זה הדמוןrmt_storage
. - אובייקט - הערך
tcontext
(הקשר יעד) מייצג את האובייקט שעליו פועלים, במקרה זה kmem. - תוצאה - הערך
tclass
(מחלקה יעד) מציין את סוג האובייקט שעליו פועלים, במקרה זהchr_file
(מכשיר תו).
השלכת ערימות משתמש וקרנל
במקרים מסוימים, המידע הכלול ביומן האירועים אינו מספיק כדי לאתר את מקור ההכחשה. לעתים קרובות כדאי לאסוף את שרשרת השיחות, כולל הליבה ומרחב המשתמש, כדי להבין טוב יותר מדוע התרחשה ההכחשה.
הגרעינים האחרונים מגדירים נקודת עקיבה בשם avc:selinux_audited
. השתמש ב-Android simpleperf
כדי להפעיל את נקודת העקיבה הזו וללכוד את שרשרת השיחות.
תצורה נתמכת
- ליבת לינוקס >= 5.10, במיוחד ענפי Android Common Kernel mainline ו- android12-5.10 נתמכים. ענף android12-5.4 נתמך גם כן. אתה יכול להשתמש
simpleperf
כדי לקבוע אם נקודת העקיבה מוגדרת במכשיר שלך:adb root && adb shell simpleperf list | grep avc:selinux_audited
. עבור גרסאות קרנל אחרות, אתה יכול לבצע commits dd81662 ו -30969bc . - זה אמור להיות אפשרי לשחזר את האירוע שאתה מנקה באגים. אירועי זמן האתחול אינם נתמכים באמצעות simpleperf; עם זאת, ייתכן שעדיין תוכל להפעיל מחדש את השירות כדי להפעיל את האירוע.
לכידת שרשרת השיחות
השלב הראשון הוא להקליט את האירוע באמצעות simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
לאחר מכן, יש להפעיל את האירוע שגרם להכחשה. לאחר מכן, יש להפסיק את ההקלטה. בדוגמה זו, באמצעות Ctrl-c
, הדוגמה הייתה צריכה להיקלט:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
לבסוף, ניתן להשתמש simpleperf report
כדי לבדוק את ה-stacktrace שנלכד. לדוגמה:
adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph" [...] Children Self Command Pid Tid Shared Object Symbol 100.00% 0.00% dmesg 3318 3318 /apex/com.android.runtime/lib64/bionic/libc.so __libc_init | -- __libc_init | -- main toybox_main toy_exec_which dmesg_main klogctl entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_syslog do_syslog selinux_syslog slow_avc_audit common_lsm_audit avc_audit_post_callback avc_audit_post_callback
שרשרת השיחות שלמעלה היא שרשרת שיחות מאוחדת של ליבה ומרחב משתמש. זה נותן לך תצוגה טובה יותר של זרימת הקוד על ידי התחלת המעקב ממרחב המשתמש עד הליבה שבה מתרחשת ההכחשה. למידע נוסף על simpleperf
, עיין בהפניה לפקודות ההפעלה של Simpleperf
מעבר למתירני
ניתן להשבית את אכיפת SELinux באמצעות ADB ב-userdebug או ב-eng builds. לשם כך, החלף תחילה את ADB ל-root על ידי הפעלת adb root
. לאחר מכן, כדי להשבית את אכיפת SELinux, הפעל:
adb shell setenforce 0
או בשורת הפקודה של הליבה (במהלך העלאת מכשיר מוקדם):
androidboot.selinux=permissive
androidboot.selinux=enforcing
או דרך bootconfig באנדרואיד 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
שימוש ב-audit2allow
הכלי audit2allow
לוקח הכחשות dmesg
וממיר אותן להצהרות מדיניות מתאימות של SELinux. ככזה, זה יכול להאיץ מאוד את פיתוח SELinux.
כדי להשתמש בו, הפעל:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
עם זאת, יש להקפיד לבחון כל תוספת פוטנציאלית להרחקת הרשאות. לדוגמה, הזנת audit2allow
את הכחשת rmt_storage
שהוצגה תוצאות קודמות בהצהרת המדיניות המוצעת של SELinux הבאה:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
זה יעניק ל- rmt
את היכולת לכתוב זיכרון ליבה, חור אבטחה בולט. לעתים קרובות הצהרות audit2allow
הן רק נקודת התחלה. לאחר שימוש בהצהרות אלו, ייתכן שיהיה עליך לשנות את תחום המקור ואת התווית של היעד, כמו גם לשלב פקודות מאקרו מתאימות, כדי להגיע למדיניות טובה. לפעמים ההכחשה הנבחנת לא אמורה להביא לשינויי מדיניות כלל; אלא יש לשנות את הבקשה הפוגענית.