SELinux מוגדר לדחייה של ברירת המחדל, כלומר כל גישה של שאליו יש לו הוק (hook) בליבה חייב להיות מותר במפורש במסגרת המדיניות. כלומר, קובץ מדיניות מורכב מכמות גדולה של מידע לגבי כללים, סוגים, כיתות, הרשאות ועוד. בחינה מלאה של SELinux לא נכלל במסמך זה, אבל הבנה של אופן הכתיבה כללי המדיניות הם חיוניים עכשיו כשיוצרים מכשירי Android חדשים. קיימת יש כבר מידע רב מאוד על SELinux. במסמכי העזרה מפורטות הצעות למקורות מידע.
קבצים של מפתחות
כדי להפעיל את SELinux, צריך לשלב את ליבת Android העדכנית ואז לשלב את הקבצים שנמצאים בספרייה system/sepolicy. לאחר הידור, הקבצים האלה כוללים את מדיניות האבטחה של הליבה של SELinux ומכסים את מערכת ההפעלה של Android במקור.
באופן כללי, לא מומלץ לשנות את קובצי system/sepolicy
ישירות. במקום זאת, מוסיפים או עורכים את קובצי המדיניות הספציפיים למכשיר בספרייה /device/manufacturer/device-name/sepolicy
. ב-Android מגרסה 8.0 ואילך, השינויים שמבצעים בקבצים האלה צריכים
משפיעה רק על המדיניות בספריית הספקים שלכם. פרטים נוספים על הפרדה של מדיניות אבטחה ציבורית ב-Android 8.0 ואילך זמינים במאמר התאמה אישית של SEPolicy ב-Android 8.0 ואילך. ללא קשר לגרסה של Android, עדיין צריך לשנות את הקבצים הבאים:
קובצי מדיניות
קבצים שמסתיימים ב-*.te
הם קובצי מקור של מדיניות SELinux, שמגדירים את הדומיינים ואת התוויות שלהם. יכול להיות שתצטרכו ליצור קובצי מדיניות חדשים ב-
/device/manufacturer/device-name/sepolicy
,
אבל מומלץ לנסות לעדכן קבצים קיימים במידת האפשר.
קובצי הקשר
קובצי הקשר הם המקום שבו מציינים את התוויות לאובייקטים.
file_contexts
מקצה תוויות לקבצים ומשתמשים בו רכיבים שונים במרחב המשתמש. כשיוצרים כללי מדיניות חדשים, יוצרים או מעדכנים את הקובץ הזה כדי להקצות תוויות חדשות לקבצים. כדי להחילfile_contexts
חדש, צריך ליצור מחדש את קובץ האימג' של מערכת הקבצים או להריץ אתrestorecon
בקובץ שרוצים לתייג מחדש. בשדרוגים, השינויים ב-file_contexts
חלים מיושמת באופן אוטומטי על המערכת ועל מחיצות נתוני המשתמש לשדרג. אפשר גם להחיל שינויים באופן אוטומטי בשדרוג למחיצות אחרות על ידי הוספת קריאות ל-restorecon_recursive
לקובץ init.board.rc אחרי שמחיצה מורכבת לקריאה וכתיבה.genfs_contexts
מקצה תוויות למערכות קבצים, כמוproc
אוvfat
, שלא תומכות במאפיינים מורחבים. ההגדרות האישיות האלה נטענות כחלק ממדיניות הליבה, אבל ייתכן שהשינויים לא ייכנסו לתוקף עבור צמתי inode בתוך ליבה, שמחייבים הפעלה מחדש או לנתק ולטעון מחדש את מערכת הקבצים כדי להחיל את השינוי באופן מלא. אפשר גם להקצות תוויות ספציפיות למחיצות ספציפיות, כמוvfat
, באמצעות האפשרותcontext=mount
.property_contexts
מקצה תוויות למאפייני מערכת Android כדי לקבוע אילו תהליכים יכולים להגדיר אותם. התהליךinit
קורא את ההגדרה הזו במהלך ההפעלה.service_contexts
מקצה תוויות לשירותי binder ב-Android עבור לקבוע אילו תהליכים יכולים להוסיף (לרשום) ולמצוא (חיפוש) binder לגבי השירות. התצורה הזו קוראת על ידי תהליךservicemanager
במהלך ההפעלה.seapp_contexts
מקצה תוויות לתהליכי אפליקציות ולספריות/data/data
. התהליךzygote
קורא את ההגדרה הזו בכל הפעלה של האפליקציה, ו-installd
קורא אותה במהלך ההפעלה.mac_permissions.xml
מקצה תגseinfo
לאפליקציות על סמך החתימה שלהם ואופציונלי, לפי שם החבילה שלהם. לאחר מכן אפשר להשתמש בתגseinfo
כמפתח בקובץseapp_contexts
כדי להקצות תווית ספציפית לכל האפליקציות עם התגseinfo
. ההגדרה הזו נקראה על ידיsystem_server
במהלך ההפעלה.keystore2_key_contexts
מקצה תוויות למרחבי שמות של Keystore 2.0. מרחב השמות הזה נאכף על ידי הדימון (daemon) של keystore2. תמיד היו ב-Keystore מרחבי שמות שמבוססים על UID/AID. בנוסף, ב-Keystore 2.0 מתבצעת אכיפה של מרחבי שמות שמוגדרים במדיניות האבטחה. תיאור מפורט של הפורמט והמוסכמות בתהליך הזה כאן אפשר למצוא את הקובץ הזה.
BoardConfig.mk makefile
אחרי עריכה או הוספה של קובצי מדיניות והקשר, מעדכנים את קובץ ה-make /device/manufacturer/device-name/BoardConfig.mk
כך שיפנה לספריית המשנה sepolicy
לכל קובץ מדיניות חדש.
מידע נוסף על המשתנים BOARD_SEPOLICY
זמין בכתובת
קובץ system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
אחרי היצירה מחדש, SELinux מופעל במכשיר. עכשיו אתם יכולים לבצע אחת מהפעולות הבאות: להתאים אישית את המדיניות של SELinux כדי להתאים לתוספות שלך מערכת ההפעלה Android כפי שמתואר ב התאמה אישית או אימות של להגדרה הקיימת, כפי שמתואר אימות.
כשקבצי המדיניות החדשים והעדכונים של BoardConfig.mk מותקנים, הגדרות המדיניות החדשות מוטמעות באופן אוטומטי בקובץ המדיניות הסופי של הליבה. למידע נוסף על האופן שבו המדיניות מבוססת על המכשיר, אפשר לעיין במאמר יצירת מדיניות.
הטמעה
כדי להתחיל לעבוד עם SELinux:
- מפעילים את SELinux בליבה:
CONFIG_SECURITY_SELINUX=y
- משנים את הפרמטר kernel_cmdline או startconfig כך:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
אוBOARD_BOOTCONFIG := androidboot.selinux=permissive
הבקשה הזו מיועדת רק לפיתוח ראשוני של מדיניות למכשיר. אחרי שתגדירו מדיניות אתחול ראשונית, תוכלו להסיר את הפרמטר הזה כדי שהמכשיר יאכוף את המדיניות או ייכשל ב-CTS. - יש להפעיל את המערכת באופן מתירני ולראות אילו דחיות של נתונים מתרחשות במהלך ההפעלה:
ב-Ubuntu 14.04 ואילך:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
ב-Ubuntu 12.04:adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- בודקים את הפלט כדי לאתר אזהרות שדומות ל-
init: Warning! Service name needs a SELinux domain defined; please fix!
. להוראות ולכלים, ראו אימות. - מזהים מכשירים וקבצים חדשים אחרים שצריך לתייג.
- משתמשים בתוויות קיימות או חדשות לאובייקטים. כדאי לעיין בקבצים
*_contexts
כדי לראות איך הדברים סומנו בעבר, ולהשתמש בידע לגבי משמעויות התוויות כדי להקצות תווית חדשה. במצב אידיאלי, זו תווית קיימת שתואמת למדיניות, אבל לפעמים נדרשת תווית חדשה, וכללי גישה לתווית הזו הדרושים. מוסיפים את התוויות לקובצי ההקשר המתאימים. - מזהים דומיינים או תהליכים שצריכים להיות להם תחומי אבטחה משלהם.
סביר להניח שתצטרכו לכתוב מדיניות חדשה לחלוטין לכל אחד מהם. הכול
בשירותים שמקורם ב-
init
, למשל, צריכים להיות שלו. הפקודות הבאות עוזרות לגלות אילו שירותים עדיין פועלים (אבל צריך לבצע את הפעולות האלה בכל השירותים):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- בודקים את השדה
init.device.rc
כדי לזהות דומיינים שאין להם סוג דומיין. כדאי להקצות לו דומיין מוקדם תהליך פיתוח כדי להימנע מהוספת כללים ל-init
או אחרת, הגישות שלinit
מבלבלות עם אלו שנמצאים מדיניות של עצמו. - מגדירים את
BOARD_CONFIG.mk
כך שישתמש במשתניBOARD_SEPOLICY_*
. פרטים על ההגדרה מופיעים בקובץ README ב-system/sepolicy
. - בודקים את הקובץ init.device.rc ו-fstab.device ו
צריך לוודא שכל שימוש ב-
mount
תואם של מערכת קבצים מתויגת, או שהאפשרותcontext= mount
היא שצוין. - בודקים כל דחייה ויוצרים מדיניות SELinux כדי לטפל בכל אחת מהן כראוי. תוכלו לעיין בדוגמאות בקטע התאמה אישית.
אתם צריכים להתחיל עם כללי המדיניות ב-AOSP ואחר כך להתבסס עליהם ולהתאמות אישיות משלכם. לקבלת מידע נוסף על אסטרטגיית המדיניות ועל לעומק על כמה מהשלבים האלה, כתיבת מדיניות SELinux.
תרחישים לדוגמה
ריכזנו כאן דוגמאות ספציפיות לנקודות חולשה שחשוב להביא בחשבון כשיוצרים תוכנה משלכם ומדיניות SELinux משויכת:
קישורים סימבוליים: מאחר שקישורים סימבוליים מופיעים כקבצים, הם מופיעים לעיתים קרובות
לקרוא אותם כקבצים, דבר שעלול להוביל לניצול לרעה. לדוגמה, כמה הרשאות
רכיבים כמו init
, משנים את ההרשאות של קבצים מסוימים,
לפעמים פתוח מדי.
לאחר מכן תוקפים עשויים להחליף את הקבצים האלה בקישורים סימבוליים כדי לקוד שהם שולטים בו, שמאפשר לתוקף להחליף קבצים שרירותיים. אבל אם אתם יודעים האפליקציה אף פעם לא חוצה קישור סימבולי, אפשר למנוע ממנה לעשות את זה עם SELinux.
קובצי מערכת: כדאי להביא בחשבון את סוג קובצי המערכת שצריך לשנות רק בשרת המערכת. עם זאת, מאחר ש-netd
, init
ו-vold
פועלים בתור root, יש להם גישה לקבצים האלה במערכת. לכן, אם netd
נפרץ, הוא עלול לפגוע בקובצים האלה ואולי גם בשרת המערכת עצמו.
באמצעות SELinux אפשר לזהות את הקבצים האלה כקובצי נתונים של שרת המערכת.
לכן הדומיין היחיד שיש לו גישת קריאה/כתיבה הוא שרת מערכת.
גם אם הדומיין netd
נפרץ, הוא לא יכול להעביר דומיינים אל
דומיין שרת מערכת ולגשת לקובצי מערכת אלו למרות שהוא פועל ברמה הבסיסית (root).
נתוני אפליקציה: דוגמה נוספת היא סיווג הפונקציות חייבות לפעול ברמה הבסיסית (root) אבל לא לקבל גישה לנתוני האפליקציה. האפשרות הזו מאוד שימושית כי אפשר להצהיר על טענות נכוֹנוּת רחבות, למשל איסור גישה לאינטרנט לדומיינים מסוימים שלא קשורים לנתוני האפליקציה.
setattr: לפקודות כמו chmod
ו-
chown
, יש לך אפשרות לזהות את קבוצת הקבצים שבה
הדומיין יכול לערוך setattr
. כל דבר מחוץ לזה יכול להיות אסור לשינויים האלה, גם על ידי משתמש root. לכן אפליקציה יכולה לפעול
chmod
ו-chown
לעומת אלה שתויגו
app_data_files
אבל לא shell_data_files
או system_data_files
.