דף זה מתאר שינויים במנהל התקן הקלסר באנדרואיד 8, מספק פרטים על השימוש ב- IPC של קלסר, ומפרט את מדיניות SELinux הנדרשת.
שינויים בנהג הקלסר
החל מ- Android 8, מסגרת ה- Android ו- HALs מתקשרים ביניהם כעת באמצעות קלסר. מכיוון שתקשורת זו מגדילה באופן דרמטי את תנועת הקלסרים, אנדרואיד 8 כוללת מספר שיפורים שנועדו לשמור על ה- IPC של קלסר מהיר. ספקי SoC ו- OEM צריכים להתמזג ישירות מהענפים הרלוונטיים של אנדרואיד 4.4, אנדרואיד -4.9 ומעלה בפרויקט הקרנל / משותף .
תחומי קלסר מרובים (הקשרים)
Common-4.4 ומעלה, כולל במעלה הזרםכדי לפצל באופן נקי את תנועת הקלסר בין קוד מסגרת (ללא תלות במכשיר) וקוד ספק (ספציפי למכשיר), אנדרואיד 8 הציגה את הרעיון של הקשר קלסר . לכל הקשר קלסר יש צומת מכשיר משלו ומנהל הקשר (שירות) משלו. ניתן לגשת למנהל ההקשר רק דרך צומת המכשיר אליו הוא שייך, וכאשר מעבירים צומת קלסר דרך הקשר מסוים, הוא נגיש מאותו הקשר רק על ידי תהליך אחר, ובכך מבודד לחלוטין את התחומים זה מזה. לקבלת פרטים על השימוש, עיין ב- vndbinder ו- vndservicemanager .
פיזור-אסוף
Common-4.4 ומעלה, כולל במעלה הזרםבמהדורות קודמות של Android, כל פיסת נתונים בשיחת קלסר הועתקה שלוש פעמים:
- פעם אחת לסדר אותו
Parcel
בתהליך ההתקשרות - פעם אחת במנהל הליבה כדי להעתיק את
Parcel
לתהליך היעד - פעם אחת כדי לבטל את סידור
Parcel
בתהליך היעד
אנדרואיד 8 משתמש באופטימיזציה של פיזור-איסוף כדי להפחית את מספר העותקים מ -3 ל- 1. במקום לבצע סדרת נתונים תחילה Parcel
, הנתונים נותרים במבנה המקורי ובפריסת הזיכרון והנהג מעתיק אותם מייד לתהליך היעד. לאחר שהנתונים נמצאים בתהליך היעד, המבנה ופריסת הזיכרון זהים וניתן לקרוא את הנתונים מבלי לדרוש עותק נוסף.
נעילה דקה
Common-4.4 ומעלה, כולל במעלה הזרםבמהדורות קודמות של Android השתמש מנהל התקן הקלסר במנעול עולמי כדי להגן מפני גישה בו זמנית למבני נתונים קריטיים. למרות שהייתה מחלוקת מינימלית על הנעילה, הבעיה העיקרית הייתה שאם חוט בעדיפות נמוכה משיג את הנעילה ואז מקדים אותו, הוא עלול לעכב ברצינות חוטים בעלי עדיפות גבוהה יותר שצריכים להשיג את אותו נעילה. זה גרם לזבל בפלטפורמה.
ניסיונות ראשוניים לפתור בעיה זו כללו השבתת קדימה תוך החזקת הנעילה הגלובלית. עם זאת, זה היה יותר פריצה מאשר פיתרון אמיתי, ובסופו של דבר נדחה על ידי הזרם ונזרק. הניסיונות הבאים התמקדו בהפיכת הנעילה לדייק יותר, שגרסתה פועלת במכשירי פיקסל מאז ינואר 2017. בעוד שרוב השינויים הללו פורסמו ברבים, בוצעו שיפורים משמעותיים בגרסאות הבאות.
לאחר שזיהינו בעיות קטנות ביישום הנעילה העדין, פיתחנו פתרון משופר עם ארכיטקטורת נעילה שונה והגשנו את השינויים בכל ענפי הליבה הנפוצים. אנו ממשיכים לבדוק יישום זה במספר רב של מכשירים שונים; מכיוון שאיננו מודעים לבעיות בולטות, זוהי ההטמעה המומלצת למכשירים המשלוחים עם Android 8.
ירושת עדיפות בזמן אמת
Common-4.4 ו- common-4.9 (במעלה הזרם בקרוב)נהג הקלסר תמיד תמך בירושת עדיפות יפה. מכיוון שמספר גדל והולך של תהליכים באנדרואיד פועל בעדיפות בזמן אמת, במקרים מסוימים כעת הגיוני שאם שרשור בזמן אמת מבצע שיחת קלסר, החוט בתהליך המטפל בשיחה פועל גם הוא בעדיפות בזמן אמת. . כדי לתמוך במקרי שימוש אלה, Android 8 מיישם כעת ירושת עדיפות בזמן אמת במנהל הקלסר.
בנוסף לירושת עדיפות ברמת העסקה, ירושת עדיפות בצומת מאפשרת לצומת (אובייקט שירות קלסר) לציין עדיפות מינימלית בה יש לבצע שיחות לצומת זה. גרסאות קודמות של אנדרואיד כבר תמכו בירושת עדיפות בצומת עם ערכים יפים, אך אנדרואיד 8 מוסיף תמיכה בירושה של צומת מדיניות בזמן אמת.
שינויים במרחב המשתמשים
אנדרואיד 8 כולל את כל השינויים במרחב המשתמשים הנדרשים לעבודה עם מנהל התקן הקלסר הנוכחי בגרעין המשותף למעט חריג אחד: היישום המקורי להשבית ירושת עדיפות בזמן אמת עבור /dev/binder
השתמש ב- ioctl . התפתחות שלאחר מכן החליפה את השליטה בירושת עדיפות לשיטה דקה יותר שהיא לכל מצב קלסר (ולא לפי הקשר). לפיכך, ה- ioctl אינו נמצא בסניף הנפוץ של Android, אלא מוגש בגרעינים הנפוצים שלנו .
ההשפעה של שינוי זה היא כי ירושת עדיפות בזמן אמת מושבתת כברירת מחדל עבור כל צומת. צוות הביצועים של Android מצא את זה מועיל לאפשר ירושת עדיפות בזמן אמת לכל הצמתים בתחום hwbinder
. כדי להשיג את אותו אפקט, בחר דובדבן שינוי זה במרחב המשתמשים.
SHA עבור גרעינים נפוצים
כדי להשיג שינויים הכרחיים במנהל הקלסר, סנכרן ל- SHA המתאים:
- Common-3.18
cc8b90c121de ANDROID: קלסר: אל תבדוק הרשאות פריו בשחזור. - נפוץ -4.4
76b376eac7a2 ANDROID: קלסר: אל תבדוק הרשאות פריו בשחזור. - משותף -4.9
ecd972d4f9b5 ANDROID: קלסר: אל תבדוק הרשאות פריו בשחזור.
באמצעות קלסר IPC
מבחינה היסטורית, תהליכי ספקים השתמשו בתקשורת בין קלסרית בין תהליכים (IPC) כדי לתקשר. באנדרואיד 8, צומת מכשיר /dev/binder
הופך לבלעדי לתהליכי מסגרת, כלומר לתהליכי ספק כבר אין גישה אליו. תהליכי ספק יכולים לגשת אל /dev/hwbinder
, אך עליהם להמיר את ממשקי ה- AIDL שלהם לשימוש ב- HIDL. עבור ספקים המעוניינים להמשיך להשתמש בממשקי AIDL בין תהליכי ספקים, אנדרואיד תומכת ב- IPC של קלסר כמתואר להלן.
vndbinder
אנדרואיד 8 תומך בתחום קלסר חדש לשימוש שירותי ספקים, אליו ניתן לגשת באמצעות /dev/vndbinder
במקום /dev/binder
. עם התוספת של /dev/vndbinder
, ל- Android יש כעת את שלושת תחומי ה- IPC הבאים:
תחום IPC | תיאור |
---|---|
/dev/binder | IPC בין תהליכי מסגרת / אפליקציה עם ממשקי AIDL |
/dev/hwbinder | IPC בין תהליכי מסגרת / ספק עם ממשקי HIDL IPC בין תהליכי ספקים עם ממשקי HIDL |
/dev/vndbinder | IPC בין תהליכי ספק / ספק עם ממשקי AIDL |
כדי ש- /dev/vndbinder
יופיע, וודא כי פריט תצורת הליבה CONFIG_ANDROID_BINDER_DEVICES
מוגדר כ- "binder,hwbinder,vndbinder"
(זהו ברירת המחדל בעצי הליבה הנפוצים של Android).
בדרך כלל, תהליכי ספקים לא פותחים ישירות את מנהל התקן הקלסר, אלא מקשרים מול ספריית libbinder
המשתמש libbinder
, אשר פותחת את מנהל התקן הקלסר. הוספת שיטה עבור ::android::ProcessState()
בוחרת את מנהל ההתקן libbinder
עבור libbinder
. תהליכי ספק צריכים להתקשר לשיטה זו לפני שהם קוראים ל- ProcessState,
IPCThreadState
, או לפני ביצוע שיחות קלסר באופן כללי. לשימוש, בצע את השיחה הבאה לאחר main()
של תהליך הספק (לקוח ושרת):
ProcessState::initWithDriver("/dev/vndbinder");
מנהל שירות
בעבר, שירותי קלסר נרשמו servicemanager
, שם ניתן היה לאחזרם בתהליכים אחרים. ב- Android 8, מנהל servicemanager
משמש כעת אך ורק על ידי תהליכי מסגרת ויישום ותהליכי ספק אינם יכולים לגשת אליו יותר.
עם זאת, שירותי הספק יכול כעת להשתמש vndservicemanager
, מופע חדש של servicemanager
כי שימושים /dev/vndbinder
במקום /dev/binder
ואשר בנויה מאותם מקורות כמו מסגרת servicemanager
. תהליכי ספק אינם צריכים לבצע שינויים כדי לדבר עם vndservicemanager
; כאשר תהליך ספק נפתח / dev/vndbinder
, dev/vndbinder
השירות עוברות אוטומטית ל- vndservicemanager
.
ה- vndservicemanager
בינארי כלול vndservicemanager
ברירת המחדל של מכשירי Android.
מדיניות SELinux
תהליכי ספק המעוניינים להשתמש בפונקציונליות קלסר כדי לתקשר זה עם זה זקוקים לדברים הבאים:
- גישה ל-
/dev/vndbinder
. - קלסר
{transfer, call}
וויםvndservicemanager
. -
binder_call(A, B)
עבור כל תחום ספק A שרוצה להתקשר לתחום ספק B דרך ממשק קלסר הספק. - אישור
{add, find}
שירותים ב-vndservicemanager
.
כדי למלא את הדרישות 1 ו -2, השתמש vndbinder_use()
:
vndbinder_use(some_vendor_process_domain);
כדי למלא דרישה 3, ה- binder_call(A, B)
לתהליכי ספק A ו- B שצריכים לדבר על קלסר יכול להישאר במקום ולא צריך לשנות שם.
כדי למלא את הדרישה 4, עליך לבצע שינויים באופן הטיפול בשמות השירות, תוויות השירות והכללים.
לפרטים על SELinux, ראה לינוקס משופרת באבטחה ב- Android . לפרטים אודות SELinux ב- Android 8.0, ראה SELinux ל- Android 8.0 .
שמות שירותים
בעבר, הספק מעבד שמות שירותים רשומים בקובץ service_contexts
והוסיף כללים מתאימים לגישה לקובץ זה. דוגמה לקובץ service_contexts
device/google/marlin/sepolicy
:
AtCmdFwd u:object_r:atfwd_service:s0 cneservice u:object_r:cne_service:s0 qti.ims.connectionmanagerservice u:object_r:imscm_service:s0 rcs u:object_r:radio_service:s0 uce u:object_r:uce_service:s0 vendor.qcom.PeripheralManager u:object_r:per_mgr_service:s0
ב- Android 8, vndservicemanager
טוען את הקובץ vndservice_contexts
במקום זאת. יש להוסיף שירותי ספקים הנודדים ל- vndservicemanager
(ואשר כבר נמצאים בקובץ service_contexts
הישן) לקובץ ה- vndservice_contexts
החדש.
תוויות שירות
בעבר, תוויות שירות כגון u:object_r:atfwd_service:s0
הוגדרו בקובץ service.te
. דוגמא:
type atfwd_service, service_manager_type;
ב- Android 8, עליך לשנות את הסוג ל- vndservice_manager_type
ולהעביר את הכלל לקובץ vndservice.te
. דוגמא:
type atfwd_service, vndservice_manager_type;
מנהל שירות שולט
בעבר כללים העניקו לדומיינים גישה להוסיף או למצוא שירותים ממנהל servicemanager
. דוגמא:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
ב- Android 8, כללים כאלה יכולים להישאר במקומם ולהשתמש באותה מחלקה. דוגמא:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;