מערכת Android ממליצה מאוד ליצרני ציוד מקורי לבדוק את ההטמעות של 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
), הוא מציין בערך מה נעשה למה. במקרה הזה, משהו ניסה להתחבר לשקע זרם Unix. - השדה
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
אלה הרכיבים העיקריים מהדחייה הזו:
- Action – הפעולה שניסית לבצע מודגשת בסוגריים מרובעים,
read write
אוsetenforce
. - Actor – הרשומה
scontext
(הקשר המקור) מייצגת את הגורם המבצע, במקרה הזה הדימוןrmt_storage
. - Object – הערך
tcontext
(הקשר יעד) מייצג האובייקט שעליו מבוצעת הפעולה, במקרה הזה, ק"מ. - תוצאה – הרשומה
tclass
(target class) מציינת את סוג האובייקט שבו מבוצעת הפעולה, במקרה הזהchr_file
(character device).
העברת מקבצים של משתמשים וליבה (kernel)
במקרים מסוימים, המידע שמופיע ביומן האירועים לא מספיק כדי לאתר את המקור לדחייה. לרוב כדאי לאסוף את שרשרת הקריאות, כולל הליבה ואזור המשתמש, כדי להבין טוב יותר למה הדחייה התרחשה.
הליבות האחרונות מגדירות נקודת מעקב בשם avc:selinux_audited
. שימוש ב-Android
simpleperf
כדי להפעיל את נקודת המעקב הזו ולתעד את ה-callchain.
תצורה נתמכת
- ליבת Linux >= 5.10, במיוחד הסתעפויות ליבה (Kernel) של Android Common
mainline
וגם
android12-5.10
נתמכים.
גרסת android12-5.4
יש תמיכה גם בהסתעפות. אפשר להשתמש ב-
simpleperf
כדי לקבוע אם נקודת המעקב שמוגדר במכשיר:adb root && adb shell simpleperf list | grep avc:selinux_audited
. לגרסאות אחרות של הליבה, אפשר לבחור את ההוספות 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
כדי לבדוק את סטאק-טריי הנתון.
לדוגמה:
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
שרשרת הקריאות שלמעלה היא ליבה מאוחדת ושרשרת קריאות של מרחב המשתמשים. זה נותן
של זרימת הקוד על ידי התחלת המעקב ממרחב המשתמשים עד ליבה (kernel) שבה
תהליך הדחייה. מידע נוסף על simpleperf
זמין
חומר עזר בנושא פקודות הפעלה פשוטות
מעבר למצב מתירני
אפשר להשבית את אכיפת SELinux באמצעות adb בגרסאות build של userdebug או eng. כדי לעשות את זה,
קודם צריך להעביר את ADB לרמה הבסיסית (root) על ידי הרצת adb root
. לאחר מכן, כדי להשבית את SELinux
אכיפה, הפעלה:
adb shell setenforce 0
או בשורת הפקודה של הליבה (במהלך ההפעלה המוקדמת של המכשיר):
androidboot.selinux=permissive
androidboot.selinux=enforcing
או דרך bootconfig ב-Android 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
הן רק
לנקודת ההתחלה. אחרי שמשתמשים בהצהרות האלה, יכול להיות שתצטרכו לשנות את הדומיין המקור והתווית של היעד, וגם לשלב מאקרואים מתאימים כדי להגיע למדיניות טובה. לפעמים הדחייה שנבדקת
לא יובילו לשינויים כלשהם במדיניות; ולא האפליקציה הפוגענית
יש לשנות את ההגדרה.