אימות 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 .
  • שחקן - The scontext (בהקשר מקור) כניסה מייצגת את השחקן, במקרה זה rmt_storage daemon.
  • חפץ - tcontext (בהקשר היעד) כניסה מייצגת את האובייקט מימושם, ב KMEM במקרה זה.
  • תוצאה - tclass הכניסה (בכיתת יעד) מציינת את סוג אובייקט מימושם, במקרה זה chr_file (מכשיר תו).

השלכת ערימות משתמש וקרנל

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

גרעינים אחרונים להגדיר tracepoint בשם avc:selinux_audited . השתמש אנדרואיד simpleperf לאפשר tracepoint זה ולתפוס את callchain.

תצורה נתמכת

  • לינוקס הקרנל> = 5.10, בפרט בענפים Kernel Common אנדרואיד האליטה החברתית ואת android12-5.10 נתמכים. Android12-5.4 הסניף נתמך גם. הנך רשאי להשתמש simpleperf כדי לקבוע אם tracepoint מוגדר במכשיר: 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 ניתן להשתמש כדי לבדוק את 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 המתג הראשון שורש ידי הפעלת 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 all -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 ההצהרות הן רק נקודת התחלה. לאחר שימוש בהצהרות אלו, ייתכן שיהיה עליך לשנות את תחום המקור ואת התווית של היעד, כמו גם לשלב פקודות מאקרו מתאימות, כדי להגיע למדיניות טובה. לפעמים ההכחשה הנבחנת לא אמורה להביא לשינויי מדיניות כלל; אלא יש לשנות את הבקשה הפוגענית.