בקרת גישה שיקול דעת (DAC)

אובייקטים ושירותים של מערכת קבצים שנוספים ל-build צריכים להיות נפרדים לעיתים קרובות, מזהים ייחודיים, שנקראים מזהי Android (AIDs). כיום, משאבים רבים כמו קבצים ושירותים משתמשים במזהי AID ליבה (מוגדרים על ידי Android) שלא לצורך, בהרבה במקרים כאלה, אפשר להשתמש במקום זאת במזהי AID של OEM (יצרן ציוד מקורי).

גרסאות קודמות של Android (Android 7.x ומטה) הרחיבו את מזהי ה-AID מנגנון באמצעות android_filesystem_config.h ספציפי למכשיר כדי לציין יכולות של מערכת קבצים ו/או מזהי OEM (יצרן ציוד מקורי) בהתאמה אישית. אבל לא הייתה אינטואיטיבית, כי היא לא תמכה בשימוש בשמות נחמדים במזהי AID של ה-OEM, דרישה לציין את המספרים הגולמיים עבור שדות של משתמשים וקבוצות ללא לשייך שם ידידותי ל-AID המספרי.

גרסאות חדשות יותר של Android (Android 8.0 ואילך) תומכות בשיטה חדשה הרחבת יכולות של מערכת קבצים. השיטה החדשה הזו תומכת הבאים:

  • מספר מיקומי מקור של קובצי תצורה (מאפשר הרחבה הגדרות build).
  • בדיקת תקינות בזמן ה-build של ערכי AID של OEM (יצרן ציוד מקורי).
  • יצירת כותרת AID מותאמת אישית של OEM (יצרן ציוד מקורי) שאפשר להשתמש בה בקובצי מקור בתור הדרושים.
  • שיוך של שם ידידותי לערך בפועל של AID של ה-OEM. תמיכה ארגומנטים של מחרוזות לא מספריות למשתמש ולקבוצה, למשל "foo" במקום '2901'.

שיפורים נוספים כוללים את הסרת android_ids[] מערך מ- system/core/libcutils/include/private/android_filesystem_config.h. הזה מערך קיים כעת ב-Bionic כמערך פרטי מלא שנוצר, עם משתמשי גישה עם getpwnam() ו-getgrnam(). (הפעולה הזו כוללת תופעת הלוואי של יצירת קבצים בינאריים יציבים לאחר שינוי של מזהי AID מרכזיים). עבור הרלוונטיים וקובץ README עם פרטים נוספים, build/make/tools/fs_config

הוספת מזהי Android (AID)

מערכת Android 8.0 הסירה את מערך android_ids[] מ-Android פרויקט קוד פתוח (AOSP). במקום זאת, כל השמות ידידותיים ל-AID נוצרים מ- system/core/libcutils/include/private/android_filesystem_config.h כשיוצרים את מערך ה-android_ids[] של ה-Bionic כלשהו כלי איסוף של define תואם AID_* ו-* הופך לשם באותיות קטנות.

לדוגמה, ב-private/android_filesystem_config.h:

#define AID_SYSTEM 1000

הופך:

  • שם ידידותי: מערכת
  • uid: 1000
  • gid: 1000

כדי להוסיף AOSP Core AID חדש, פשוט מוסיפים את #define אל קובץ הכותרת android_filesystem_config.h. ה-AID הוא שנוצרו ב-build ויהיו זמינות לממשקים שמשתמשים במשתמשים ובקבוצות ארגומנטים. הכלי בודק שה-AID החדש לא נכלל ב-APP או ב-OEM טווחים; הוא גם מכבד שינויים בטווחים האלה, והוא צריך לפעול באופן אוטומטי להגדיר מחדש שינויים או טווחים חדשים ששמורים ל-OEM (יצרן הציוד המקורי).

הגדרת מזהי AID

כדי להפעיל את מנגנון AID החדש, יש להגדיר את TARGET_FS_CONFIG_GEN בקטע קובץ BoardConfig.mk. המשתנה הזה מכיל רשימה של הגדרות באופן שמאפשר לכם לצרף קבצים לפי הצורך.

לפי המוסכמה, השם של קובצי התצורה הוא config.fs, אבל אפשר להשתמש בכל שם. config.fs קבצים נמצאים ב Python ConfigParser ini format כולל קטע אותיות (להגדרת קובץ) יכולות המערכת) והקטע AIDs (להגדרת מכשירי OEM AID).

הגדרת קטע האותיות

בקטע 'כובעים' אפשר להגדיר קובץ יכולות מערכת באובייקטים של מערכת קבצים בתוך ה-build (מערכת הקבצים עצמו חייב לתמוך בפונקציונליות הזו).

הפעלה של שירות יציב ברמה הבסיסית (root) ב-Android גורמת ל חבילה לבדיקת תאימות (CTS) כשלים, דרישות קודמות לשמירה על יכולת במהלך הפעלת בתהליך או בשירות שנדרשים בהגדרה של יכולות, ואז משתמשים setuid/setgid ל-AID מתאים להרצה. באותיות רישיות, יכול לדלג על הדרישות האלה ולבקש מהליבה (kernel) לעשות זאת בשבילכם. כשהבקרה היא הועבר אל main(), התהליך שלך כבר כולל את היכולות לצרכים שלכם כדי שהשירות יוכל להשתמש במשתמש ובקבוצה שאינם Root (זו השיטה המועדפת כדי להתחיל שירותים מוגבלים).

הקטע Caps משתמש בתחביר הבא:

קטע ערך הגדרה
[path] נתיב של מערכת הקבצים להגדרה. נתיב שמסתיים ב-/ נחשב ל-dir, אחר זה קובץ.

יש שגיאה לציין כמה קטעים עם אותם מקטעים [path] בקבצים שונים. בגרסאות Python <= 3.2, הפרמטר ייתכן שאותו קובץ יכיל קטעים שיעקפו את הקטע הקודם. ב-Python 3.2, הוא מוגדר למצב מחמיר.
mode מצב קובץ אוקטלי מצב קובץ אוקטלי חוקי בן 3 ספרות לפחות. אם צוין 3, אז הוא עם קידומת 0, אחרת המערכת תשתמש במצב כפי שהוא.
user AID_<user> C define כדי לציין AID תקף או את השם הידידותי (למשל, גם AID_RADIO וגם radio יתקבלו). שפת תרגום להגדיר AID מותאם אישית, ראו הגדרת את הקטע AID.
group AID_<group> בדיוק כמו המשתמש.
caps מכסה* השם כפי שהוצהר ב- bionic/libc/kernel/uapi/linux/capability.h בלי CAP_ בהתחלה. מותר להשתמש באותיות רישיות ומעורבות. אפשר גם הגולמיים:
  • בינארית (0b0101)
  • octal (0455)
  • int (42)
  • הקסדצימלי (0xFF)
יש להפריד בין אותיות גדולות אחדות באמצעות רווחים לבנים.

לדוגמה, ראו שימוש בקובץ יכולות המערכת.

הגדרת הקטע AID

הקטע AID מכיל מזהי OEM AIDs, עם התחביר הבא:

קטע ערך הגדרה
[AID_<name>] <name> יכול להכיל תווים בקבוצה אותיות רישיות, מספרים וקווים תחתונים. הגרסה באותיות קטנות משמשת בתור שם ידידותי. קובץ הכותרת שנוצר להכללת הקוד משתמש באותה AID_<name>

יש שגיאה לציין כמה קטעים עם אותם מקטעים AID_<name> (לא תלוי-רישיות עם אותן מגבלות כמו [path]).

<name> חייב להתחיל בשם חלוקה כדי לוודא שהיא לא מתנגשת עם מקורות שונים.
value <מספר> מחרוזת מספר חוקית בסגנון C (הקסדצימלית, אוקטלית, בינארית ועשרונית).

אפשר לציין כמה מקטעים עם אותה אפשרות ערך.

צריך לציין אפשרויות ערכים בטווח המתאים למחיצה בשימוש ב-<name>. רשימת המחיצות החוקיות והמחיצות התואמות שלהן הטווחים מוגדרים ב-system/core/libcutils/include/private/android_filesystem_config.h. האפשרויות הן:
  • מחיצת ספקים
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • מחיצת מערכת
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • מחיצת ODM
    • AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • קטגוריית מוצרים
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • מחיצת System_ext
    • AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

דוגמאות לשימוש זמינות במאמר הגדרת OEM (יצרן ציוד מקורי) שמות AID ושימוש ב-OEM AIDs.

דוגמאות לשימוש

בדוגמאות הבאות מוסבר איך להגדיר AID של OEM, ואיך להשתמש בו, להפעיל יכולות של מערכת קבצים. שמות AID של ה-OEM ([AID_name]) חייב להתחיל ב- שם מחיצה, כגון 'vendor_' כדי להבטיח שלא יתנגשו שמות AOSP או מחיצות אחרות.

הגדרת שמות AID של OEM (יצרן ציוד מקורי)

כדי להגדיר AID של OEM, יש ליצור קובץ config.fs ולהגדיר את ערך ה-AID. לדוגמה, ב-device/x/y/config.fs, מגדירים את הבאים:

[AID_VENDOR_FOO]
value: 2900

אחרי יצירת הקובץ, צריך להגדיר את המשתנה TARGET_FS_CONFIG_GEN ומצביעים עליו בBoardConfig.mk. לדוגמה, ב- device/x/y/BoardConfig.mk, מגדירים את האפשרויות הבאות:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

המערכת יכולה עכשיו להשתמש באופן כללי ב-AID המותאם אישית ב-build חדש.

שימוש ב-OEM AIDs

כדי להשתמש ב-OEM AID, יש לכלול בקוד C את הפרמטר oemaids_headers Makefile, #include "generated_oem_aid.h", ואז להתחיל להשתמש בהצהרה שהוצהרה מזהים. לדוגמה, ב-my_file.c, צריך להוסיף את הפרטים הבאים:

#include "generated_oem_aid.h"
…

If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

לקובץ Android.bp המשויך, צריך להוסיף את הפרטים הבאים:

header_libs: ["oemaids_headers"],

אם משתמשים בקובץ Android.mk, צריך להוסיף את הפרטים הבאים:

LOCAL_HEADER_LIBRARIES := oemaids_headers

כדאי להשתמש בשמות ידידותיים

ב-Android 9, ניתן להשתמש בשם הידידותי של כל ממשק שתומך בשמות AID. לדוגמה:

  • באמצעות פקודת chown ב-some/init.rc:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • ב-service ב-some/init.rc:
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

בגלל שהמיפוי הפנימי משם ידידותי ל-uid מבוצע על ידי /vendor/etc/passwd וגם /vendor/etc/group, הספק חייבים לטעון את המחיצה.

שמות ידידותיים

Android 9 כולל תמיכה בשיוך שם ידידותי עם ערך ה-AID של ה-OEM בפועל. אפשר להשתמש במחרוזת לא מספרית ארגומנטים למשתמש ולקבוצה, כלומר 'vendor_foo' במקום '2901'.

המרה מ-AID לשמות ידידותיים

עבור מזהי OEM (יצרן ציוד מקורי), Android 8.x נדרשו לשימוש oem_#### עם getpwnam ופונקציות דומות, כמו היטב במקומות שבהם מטפלים בחיפושי מידע עם getpwnam (כמו init סקריפטים). ב-Android 9 אפשר להשתמש בחברים getpwnam ו-getgrnam ב-Bionic עבור להמיר ממזהי Android (AID) לשמות ידידותיים, ולהפך.

שימוש ביכולות של מערכת קבצים

כדי להפעיל יכולות של מערכת קבצים, צריך ליצור קטע Caps קובץ config.fs. לדוגמה, ב- device/x/y/config.fs, צריך להוסיף את הקטע הבא:

[system/bin/foo_service]
mode: 0555
user: AID_VENDOR_FOO
group: AID_SYSTEM
caps: SYS_ADMIN | SYS_NICE

אחרי יצירת הקובץ, מגדירים את TARGET_FS_CONFIG_GEN כך שיצביע על של הקובץ הזה ב-BoardConfig.mk. לדוגמה, ב- device/x/y/BoardConfig.mk, מגדירים את האפשרויות הבאות:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

כשהשירות vendor_foo מופעל, הוא מתחיל עם היכולות CAP_SYS_ADMIN ו-CAP_SYS_NICE ללא שיחות setuid ו-setgid. בנוסף, מדיניות SELinux של שירות vendor_foo כבר לא בתוקף צריכה יכולת setuid ו-setgid נמחק.

הגדרת שינויים (Android 6.x-7.x)

מערכת Android 6.0 הועברה אל fs_config והמבנה המשויך אליו הגדרות (system/core/include/private/android_filesystem_config.h) אל system/core/libcutils/fs_config.c שבהם אפשר לעדכן אותם או בוטלה על ידי קבצים בינאריים שהותקנו ב- /system/etc/fs_config_dirs והקבוצה /system/etc/fs_config_files שימוש בהתאמה ובניתוח נפרדים כללים לספריות וקבצים (שבהם יכולים להשתמש בביטויים נוספים של glob) ל-Android יש אפשרות לטפל בספריות וקבצים בשתי טבלאות שונות. הגדרות המבנה ב-system/core/libcutils/fs_config.c לא מותרת רק קריאה של ספריות וקבצים בזמן הריצה, אבל המארח יכול להשתמש את אותם קבצים במהלך זמן ה-build כדי ליצור תמונות של מערכת הקבצים כמו ${OUT}/system/etc/fs_config_dirs והקבוצה ${OUT}/system/etc/fs_config_files.

למרות ששיטת הביטול של הרחבת מערכת הקבצים הוחלפה על ידי במערכת התצורה המודולרית שהוצגה ב-Android 8.0, עדיין אפשר להשתמש אם יש צורך. בקטעים הבאים מפורט איך ליצור ולכלול לשנות את הקבצים ולהגדיר את מערכת הקבצים.

יצירת קבצים לשינוי מברירת המחדל

אפשר ליצור קבצים בינאריים מיושרים /system/etc/fs_config_dirs והקבוצה /system/etc/fs_config_files באמצעות כלי fs_config_generate בbuild/tools/fs_config. הכלי משתמש בפונקציית הספרייה libcutils (fs_config_generate()) כדי לנהל את הדרישות של בקרת האקלים בתוך מאגר נתונים זמני ומגדיר כללים לקובץ הכללה כדי לבסס את כללי DAC.

כדי להשתמש בו, צריך ליצור קובץ הכללה ב- device/vendor/device/android_filesystem_config.h שמשמש כשינוי מברירת המחדל. הקובץ חייב להשתמש ב פורמט structure fs_path_config הוגדר בפורמט system/core/include/private/android_filesystem_config.h עם אתחולי המבנה הבאים עבור סמלים של ספריות וקבצים:

  • לספריות, צריך להשתמש ב-android_device_dirs[].
  • לקבצים: android_device_files[].

כשלא משתמשים ב-android_device_dirs[] וב- android_device_files[], אפשר להגדיר NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS והקבוצה NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (ניתן לעיין ב דוגמה למטה). אפשר גם לציין את השינוי מברירת המחדל קובץ באמצעות TARGET_ANDROID_FILESYSTEM_CONFIG_H בלוח עם שם בסיס שנאכף android_filesystem_config.h.

כולל קבצים לשינוי מברירת המחדל

כדי לכלול קבצים, צריך לוודא שהשדה PRODUCT_PACKAGES כולל fs_config_dirs ו/או fs_config_files כדי שתהיה אפשרות להתקין אותם ב-/system/etc/fs_config_dirs ו /system/etc/fs_config_files, בהתאמה. מערכת ה-build חיפושים אחר android_filesystem_config.h מותאם אישית ב- $(TARGET_DEVICE_DIR), כאשר BoardConfig.mk קיים. אם הקובץ קיים במקום אחר, צריך להגדיר משתנה תצורה של לוח TARGET_ANDROID_FILESYSTEM_CONFIG_H כדי להצביע למיקום הזה.

הגדרת מערכת הקבצים

כדי להגדיר את מערכת הקבצים ב-Android 6.0 ואילך:

  1. יצירה של $(TARGET_DEVICE_DIR)/android_filesystem_config.h חדש.
  2. הוספת fs_config_dirs ו/או fs_config_files אל PRODUCT_PACKAGES בקובץ התצורה של הלוח (למשל, $(TARGET_DEVICE_DIR)/device.mk).

דוגמה לשינוי מברירת המחדל

בדוגמה הזו מוצג תיקון לעקיפת system/bin/glgps לדימון (daemon) כדי להוסיף תמיכה לנעילת מצב שינה הספרייה device/vendor/device. יש להשאיר את חשוב לזכור:

  • כל רשומת מבנה היא המצב, uid, gid, יכולות והשם. system/core/include/private/android_filesystem_config.h הוא נכללות באופן אוטומטי כדי לספק את המניפסט #defines (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND).
  • הקטע android_device_files[] כולל פעולה כדי בטל את הגישה אל system/etc/fs_config_dirs כאשר לא צוין, משמש כהגנה נוספת על DAC עקב היעדר תוכן לספרייה לברירת המחדל. עם זאת, מדובר בהגנה חלשה; אם למישהו יש שליטה על /system, בדרך כלל הם יכולים לעשות כל מה שהם רוצים.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h
new file mode 100644
index 0000000..874195f
--- /dev/null
+++ b/android_filesystem_config.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* This file is used to define the properties of the file system
+** images generated by build tools (eg: mkbootfs) and
+** by the device side of adb.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+/* static const struct fs_path_config android_device_dirs[] = { }; */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+static const struct fs_path_config android_device_files[] = {
+  { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND),
"system/bin/glgps" },
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+};


diff --git a/device.mk b/device.mk
index 0c71d21..235c1a7 100644
--- a/device.mk
+++ b/device.mk
@@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \
     libwpa_client \
     hostapd \
     wpa_supplicant \
-    wpa_supplicant.conf
+    wpa_supplicant.conf \
+    fs_config_files

 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)

העברת מערכות קבצים מגרסאות קודמות

כשמעבירים מערכות קבצים מ-Android 5.x ומגרסאות קודמות, חשוב לזכור: Android 6.x

  • מסירה חלק מהכללות, מבנים והגדרות מוטבעות.
  • נדרשת הפניה אל libcutils במקום לפעול ישירות מ-system/core/include/private/android_filesystem_config.h. קובצי הפעלה פרטיים של יצרן המכשיר שתלויים ב system/code/include/private_filesystem_config.h של הקובץ או מבני ספריות או fs_config חייבים להוסיף libcutils של הספריות.
  • נדרשים עותקי סניף פרטי של יצרן המכשיר system/core/include/private/android_filesystem_config.h עם תוכן נוסף ביעדים קיימים שצריך להעביר device/vendor/device/android_filesystem_config.h.
  • שומרת את הזכות להחיל אמצעי בקרת גישה נדרשים (MAC) של SELinux על קובצי תצורה במערכת היעד, הטמעות שכוללות שמטורגטים לקובצי הפעלה באמצעות fs_config() חייבים להבטיח גישה.