הטמעת SELinux

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:

  1. מפעילים את SELinux בליבה: CONFIG_SECURITY_SELINUX=y
  2. משנים את הפרמטר kernel_cmdline או startconfig כך:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    או
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    הבקשה הזו מיועדת רק לפיתוח ראשוני של מדיניות למכשיר. אחרי שתגדירו מדיניות אתחול ראשונית, תוכלו להסיר את הפרמטר הזה כדי שהמכשיר יאכוף את המדיניות או ייכשל ב-CTS.
  3. יש להפעיל את המערכת באופן מתירני ולראות אילו דחיות של נתונים מתרחשות במהלך ההפעלה:
    ב-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
    
  4. בודקים את הפלט כדי לאתר אזהרות שדומות ל-init: Warning! Service name needs a SELinux domain defined; please fix!. להוראות ולכלים, ראו אימות.
  5. מזהים מכשירים וקבצים חדשים אחרים שצריך לתייג.
  6. משתמשים בתוויות קיימות או חדשות לאובייקטים. כדאי לעיין בקבצים *_contexts כדי לראות איך הדברים סומנו בעבר, ולהשתמש בידע לגבי משמעויות התוויות כדי להקצות תווית חדשה. במצב אידיאלי, זו תווית קיימת שתואמת למדיניות, אבל לפעמים נדרשת תווית חדשה, וכללי גישה לתווית הזו הדרושים. מוסיפים את התוויות לקובצי ההקשר המתאימים.
  7. מזהים דומיינים או תהליכים שצריכים להיות להם תחומי אבטחה משלהם. סביר להניח שתצטרכו לכתוב מדיניות חדשה לחלוטין לכל אחד מהם. הכול בשירותים שמקורם ב-init, למשל, צריכים להיות שלו. הפקודות הבאות עוזרות לגלות אילו שירותים עדיין פועלים (אבל צריך לבצע את הפעולות האלה בכל השירותים):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. בודקים את השדה init.device.rc כדי לזהות דומיינים שאין להם סוג דומיין. כדאי להקצות לו דומיין מוקדם תהליך פיתוח כדי להימנע מהוספת כללים ל-init או אחרת, הגישות של init מבלבלות עם אלו שנמצאים מדיניות של עצמו.
  9. מגדירים את BOARD_CONFIG.mk כך שישתמש במשתני BOARD_SEPOLICY_*. פרטים על ההגדרה מופיעים בקובץ README ב-system/sepolicy.
  10. בודקים את הקובץ init.device.rc ו-fstab.device ו צריך לוודא שכל שימוש ב-mount תואם של מערכת קבצים מתויגת, או שהאפשרות context= mount היא שצוין.
  11. בודקים כל דחייה ויוצרים מדיניות 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.