לרוב, אובייקטים ושירותים של מערכת קבצים שנוספו לגרסה היציבה זקוקים למזהים ייחודיים נפרדים, שנקראים מזהי Android (AID). נכון לעכשיו, משאבים רבים כמו קבצים ושירותים משתמשים ב-AIDs ליבה (שהוגדרו על ידי Android) ללא צורך. במקרים רבים אפשר להשתמש במקום זאת ב-AIDs של יצרן ציוד מקורי (שהוגדרו על ידי יצרן ציוד מקורי).
בגרסאות קודמות של Android (Android 7.x ומטה) הרחבו את מנגנון ה-AID
באמצעות קובץ android_filesystem_config.h
ספציפי למכשיר כדי לציין יכולות של מערכת הקבצים ו/או מזהי OEM (יצרן ציוד מקורי) בהתאמה אישית. עם זאת, המערכת הזו לא הייתה אינטואיטיבית כי היא לא תמכה בשמות נוחים למזהי AID של יצרני ציוד מקורי, והייתם צריכים לציין את המספר הגולמי בשדות של משתמשים וקבוצות, בלי אפשרות לשייך שם ידידותי למזהה ה-AID המספרי.
בגרסאות חדשות יותר של Android (Android 8.0 ואילך) יש תמיכה בשיטה חדשה להרחבת היכולות של מערכת הקבצים. השיטה החדשה תומכת באפשרויות הבאות:
- מספר מיקומי מקור של קובצי התצורה (הפעלת הגדרות build שניתן להרחיב).
- בדיקת תקינות של ערכי AID של יצרן ציוד מקורי (OEM) בזמן ה-build.
- יצירת כותרת OEM AID בהתאמה אישית שאפשר להשתמש בה בקובצי מקור לפי הצורך.
- שיוך של שם ידידותי לערך ה-AID בפועל של יצרן הציוד המקורי. תמיכה בארגומנטים של מחרוזות לא מספריות למשתמש ולקבוצה, כלומר "foo" במקום "2901".
שיפורים נוספים כוללים הסרה של המערך android_ids[]
מ-system/core/libcutils/include/private/android_filesystem_config.h
. המערך הזה קיים עכשיו ב-Bionic כמערך פרטי לחלוטין, עם רכיבי גישה עם getpwnam()
ו-getgrnam()
. (התוצאה הלוואי של השיטה הזו היא יצירת קובצי בינארי יציבים כש-AIDs הליבה משתנים). תוכלו למצוא כלים וקובץ 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
הופך ל-:
- שם חיבה: system
- uid: 1000
- gid: 1000
כדי להוסיף AID חדש של הליבה של AOSP, פשוט מוסיפים את #define
לקובץ הכותרת android_filesystem_config.h
. ה-AID נוצר בזמן ה-build וזמין לממשקים שמשתמשים בארגומנטים של משתמשים וקבוצות. הכלי מאמת שה-AID החדש לא נמצא בטווח של האפליקציה או של יצרן הציוד המקורי. הוא גם מתייחס לשינויים בטווחים האלה, ועליו להגדיר מחדש באופן אוטומטי במקרה של שינויים או טווחים חדשים שמוגדרים לשימוש יצרן הציוד המקורי.
הגדרת AIDs
כדי להפעיל את מנגנון AID החדש, צריך להגדיר את TARGET_FS_CONFIG_GEN
בקובץ BoardConfig.mk
. המשתנה הזה מכיל רשימה של קובצי תצורה, ומאפשר לצרף קבצים לפי הצורך.
לפי המוסכמה, קובצי התצורה נקראים config.fs
, אבל בפועל אפשר להשתמש בכל שם. קובצי config.fs
הם בפורמט ini של Python ConfigParser, והם כוללים קטע caps (להגדרת יכולות של מערכת הקבצים) וקטע AIDs (להגדרת AIDs של יצרני ציוד מקורי).
הגדרת הקטע של המגבלות
הקטע caps תומך בהגדרת יכולות של מערכת קבצים באובייקטים של מערכת הקבצים בתוך ה-build (גם מערכת הקבצים עצמה צריכה לתמוך בפונקציונליות הזו).
הפעלת שירות יציב ברמה הבסיסית (root) ב-Android גורמת לכשל של חבילת בדיקת התאימות (CTS), ולכן הדרישות הקודמות לשמירת היכולת בזמן הפעלת
תהליך או שירות היו קשורות להגדרה של יכולות ואז לשימוש ב-setuid
/setgid
ב-AID תקין כדי לפעול. בעזרת כובע, אפשר לדלג על הדרישות האלה ולאפשר לליבה לבצע את הפעולות האלה בשבילכם. כשהשליטה מועברת ל-main()
, לתהליך כבר יש את היכולות הנדרשות כדי שהשירות יוכל להשתמש במשתמש ובקבוצה שאינם משתמש root (זוהי הדרך המועדפת להפעלת שירותים עם הרשאות).
הקטע caps משתמש בהתחביר הבא:
קטע | ערך | הגדרה |
---|---|---|
[path] |
הנתיב למערכת הקבצים שרוצים להגדיר. נתיב שמסתיים ב-/ נחשב לתיקייה, אחרת הוא נחשב לקובץ.
אסור לציין כמה קטעים עם אותו [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 |
cap* | השם כפי שהוצהר ב-bionic/libc/kernel/uapi/linux/capability.h , ללא CAP_ המוביל. מותר להשתמש באותיות רישיות ובאותיות רגילות. אפשר גם להשתמש ב-Caps בפורמט הגולמי:
|
דוגמה לשימוש מפורטת במאמר שימוש ביכולות של מערכת הקבצים.
הגדרת הקטע AID
הקטע AID מכיל מזהי AID של יצרני ציוד מקורי, והוא משתמש בתחביר הבא:
קטע | ערך | הגדרה |
---|---|---|
[AID_<name>] |
השדה <name> יכול להכיל תווים מהקבוצה: אותיות רישיות, ספרות וקווים תחתונים. הגרסה באותיות קטנות משמשת בתור השם הידידותי. קובץ הכותרת שנוצר להכללת הקוד משתמש ב-AID_<name> המדויק.
כדאי לציין מספר מקטעים עם אותם AID_<name> (לא תלויי-רישיות עם אותן מגבלות כמו [path] ). <name> חייב להתחיל בשם חלוקה כדי לוודא שהוא לא מתנגש עם מקורות שונים. |
|
value |
<number> | מחרוזת מספרים תקינה בסגנון C (קסדצימלי, אוקטלי, בינארי ודצימלי).
אפשר לציין כמה מקטעים עם אותה אפשרות ערך. יש לציין את אפשרויות הערך בטווח התואם למחיצה שמשמשת ב- <name> . רשימת המחיצות החוקיות והטווחים התואמים שלהן מוגדרים ב-system/core/libcutils/include/private/android_filesystem_config.h .
האפשרויות הן:
|
דוגמאות לשימוש מפורטות במאמרים הגדרת שמות של מזהי AID של יצרן ציוד מקורי ושימוש במזהי AID של יצרן ציוד מקורי.
דוגמאות לשימוש
בדוגמאות הבאות מוסבר איך מגדירים מזהה OEM AID ומשתמשים בו, ואיך מפעילים את היכולות של מערכת הקבצים. שמות של OEM (יצרן ציוד מקורי) ([AID_name]) חייבים להתחיל בשם חלוקה כמו 'vendor_', כדי להבטיח שהם לא מתנגשים עם שמות AOSP עתידיים או מחיצות אחרות.
הגדרת שמות של מזהי AID של יצרני ציוד מקורי
כדי להגדיר מזהה 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 בהתאמה אישית בגרסה חדשה.
שימוש במזהי AID של יצרני ציוד מקורי
כדי להשתמש ב-AID של יצרן ציוד מקורי, צריך לכלול את oemaids_headers
ב-Makefile המשויך בקוד C, להוסיף את #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 לשמות ידידותיים
ב-Android 8.x, מזהי AID של יצרני ציוד מקורי נדרשו להשתמש ב-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 במאגר, ומגדיר כללים לקובץ include כדי להטמיע את כללי ה-DAC.
כדי להשתמש בה, יוצרים קובץ include ב-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 ואילך:
- יוצרים את הקובץ
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - מוסיפים את
fs_config_dirs
ו/אוfs_config_files
ל-PRODUCT_PACKAGES
בקובץ התצורה של הלוח (למשל,$(TARGET_DEVICE_DIR)/device.mk
).
דוגמה לשינוי מברירת המחדל
בדוגמה הזו מוצג תיקון לשינוי של הדימון system/bin/glgps
כדי להוסיף תמיכה ב-wake lock בספרייה device/vendor/device
. חשוב לזכור:
- כל רשומה ב-structure היא המצב, 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()
חייבות להבטיח גישה.