אימות SELinux

אנדרואיד מעודדת בחום יצרני 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. לאחר מכן, יצרנים יכולים לתקן התנהגות גרועה זו, על ידי שינויים בתוכנה, מדיניות 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 הן רק נקודת התחלה. לאחר שימוש בהצהרות אלו, ייתכן שיהיה עליך לשנות את תחום המקור ואת התווית של היעד, כמו גם לשלב פקודות מאקרו מתאימות, כדי להגיע למדיניות טובה. לפעמים ההכחשה הנבחנת לא אמורה להביא לשינויי מדיניות כלל; אלא יש לשנות את הבקשה הפוגענית.