הקשחת מסגרת מדיה

כדי לשפר את אבטחת המכשיר, אנדרואיד 7.0 מפרקת את תהליך mediaserver המונוליטי למספר תהליכים עם הרשאות ויכולות מוגבלות רק לאלו הנדרשות בכל תהליך. שינויים אלה מפחיתים את פגיעות האבטחה של מסגרת המדיה על ידי:

  • פיצול רכיבי צינור AV לתהליכים ארגז חול ספציפיים לאפליקציה.
  • הפעלת רכיבי מדיה הניתנים לעדכון (מחלצים, קודקים וכו').

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

יצרני OEM וספקי SoC צריכים לעדכן את שינויי ה-HAL והמסגרת שלהם כדי להפוך אותם למתאימים לארכיטקטורה החדשה. באופן ספציפי, מכיוון שקוד אנדרואיד שסופק על ידי הספק מניח לעתים קרובות שהכל פועל באותו תהליך, על הספקים לעדכן את הקוד שלהם כדי להעביר נקודות אחיזה מקוריות ( native_handle ) שיש להן משמעות בין תהליכים. להתייחסות ליישום שינויים הקשורים להקשחת מדיה, עיין frameworks/av ו- frameworks/native .

שינויים אדריכליים

גרסאות קודמות של אנדרואיד השתמשו בתהליך יחיד mediaserver של שרת מדיה עם הרבה מאוד הרשאות (גישה למצלמה, גישה לאודיו, גישה למנהלי התקן וידאו, גישה לקבצים, גישה לרשת וכו'). אנדרואיד 7.0 מפצלת את תהליך mediaserver למספר תהליכים חדשים שכל אחד מהם דורש קבוצה קטנה בהרבה של הרשאות:

התקשות שרת מדיה

איור 1. שינויים בארכיטקטורה עבור התקשות שרת מדיה

ארכיטקטורה חדשה זו מבטיחה שגם אם תהליך נפגע, לקוד זדוני אין גישה לסט המלא של ההרשאות שהיו בעבר על ידי שרת המדיה. תהליכים מוגבלים על ידי מדיניות SElinux ו-seccomp.

הערה: בגלל תלות בספק, קודקים מסוימים עדיין פועלים mediaserver וכתוצאה מכך מעניקים mediaserver יותר הרשאות מהנדרש. באופן ספציפי, Widevine Classic ממשיך לרוץ mediaserver עבור אנדרואיד 7.0.

שינויים ב-MediaServer

באנדרואיד 7.0, תהליך mediaserver קיים להנעת השמעה והקלטה, למשל העברת וסנכרון של חוצצים בין רכיבים ותהליכים. תהליכים מתקשרים באמצעות מנגנון הבינדר הסטנדרטי.

בהפעלת הפעלה מקומית רגילה של קבצים, האפליקציה מעבירה מתאר קבצים (FD) לשרת mediaserver (בדרך כלל באמצעות MediaPlayer Java API), mediaserver :

  1. עוטף את ה-FD לאובייקט Binder DataSource המועבר לתהליך החילוץ, המשתמש בו כדי לקרוא מהקובץ באמצעות Binder IPC. (מחלץ המדיה לא מקבל את ה-FD אלא גורם ל-Binder שיחות חזרה לשרת mediaserver כדי לקבל את הנתונים.)
  2. בוחן את הקובץ, יוצר את המחלץ המתאים לסוג הקובץ (למשל MP3Extractor, או mediaserver ), ומחזיר ממשק Binder עבור המחלץ לתהליך שרת המדיה.
  3. מבצע קריאות IPC של Binder למחלץ כדי לקבוע את סוג הנתונים בקובץ (למשל נתוני MP3 או H.264).
  4. קורא לתהליך ה- mediacodec ליצור קודקים מהסוג הנדרש; מקבל ממשקי Binder עבור רכיבי codec אלה.
  5. מבצע קריאות חוזרות של Binder IPC לחולץ כדי לקרוא דוגמאות מקודדות, משתמש ב-Binder IPC כדי לשלוח נתונים מקודדים לתהליך ה- mediacodec לצורך פענוח, ומקבל נתונים מפוענחים.

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

MediaCodecService שינויים

שירות ה-Codec הוא המקום שבו חיים המקודדים והמפענחים. עקב תלות בספקים, עדיין לא כל ה-codec חיים בתהליך ה-codec. באנדרואיד 7.0:

  • מפענחים ומקודדי תוכנה לא מאובטחים חיים בתהליך ה-Codec.
  • מפענחים מאובטחים mediaserver חומרה חיים בשרת המדיה (ללא שינוי).

יישום (או שרת מדיה) קורא לתהליך ה-Codec כדי ליצור רכיב-Codec מהסוג הנדרש, ואז קורא לאותו Codec להעביר נתונים מקודדים ולאחזר נתונים מפוענחים (לפענוח) או להעביר נתונים מפוענחים ולאחזר נתונים מקודדים (לקידוד) . העברת נתונים מ-Codec וממנה משתמשת כבר בזיכרון משותף, כך שתהליך זה אינו משתנה.

שינויים ב-MediaDrmServer

שרת DRM משמש בעת הפעלת תוכן מוגן DRM, כגון סרטים ב-Google Play Movies. הוא מטפל בפענוח הנתונים המוצפנים בצורה מאובטחת, וככזה יש לו גישה לאחסון תעודות ומפתחות ורכיבים רגישים אחרים. עקב תלות בספקים, תהליך ה-DRM עדיין אינו בשימוש בכל המקרים.

שינויים ב- AudioServer

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

CameraServer שינויים

ה-CameraServer שולט במצלמה ומשמש בעת הקלטת וידאו כדי להשיג פריימים של וידאו מהמצלמה ולאחר מכן להעביר אותם ל- mediaserver לטיפול נוסף. לפרטים על שינויים והנחיית יישום עבור שינויים ב-CameraServer, עיין ב- Camera Framework Hardening .

שינויים בשירות Extractor

שירות החילוץ מארח את החולצים , רכיבים המנתחים את פורמטי הקבצים השונים הנתמכים על ידי מסגרת המדיה. שירות החילוץ הוא הפחות מועדף מבין כל השירותים - הוא לא יכול לקרוא FDs ולכן במקום זאת הוא מבצע שיחות אל ממשק Binder (שמסופק לו על ידי mediaserver for כל הפעלת השמעה) כדי לגשת לקבצים.

יישום (או mediaserver ) מבצע קריאה לתהליך החילוץ כדי להשיג IMediaExtractor , קורא לאותו IMediaExtractor להשיג IMediaSources עבור המסלול הכלול בקובץ, ולאחר מכן קורא ל- IMediaSources לקרוא מהם נתונים.

כדי להעביר את הנתונים בין תהליכים, האפליקציה (או mediaserver ) כוללת את הנתונים ב-ply-Parcel כחלק מעסקת הבינדר או משתמשת בזיכרון משותף:

  • שימוש בזיכרון משותף דורש קריאת Binder נוספת כדי לשחרר את הזיכרון המשותף אך הוא מהיר יותר וצורך פחות חשמל עבור מאגרים גדולים.
  • השימוש ב-Parcel דורש העתקה נוספת אך הוא מהיר יותר וצורך פחות חשמל עבור מאגרים קטנים מ-64KB.

יישום

כדי לתמוך במעבר של רכיבי MediaDrm ו- MediaCrypto לתהליך ה- mediadrmserver החדש, על הספקים לשנות את שיטת ההקצאה למאגרים מאובטחים כדי לאפשר שיתוף מאגרים בין תהליכים.

במהדורות קודמות של אנדרואיד, מאגרים מאובטחים מוקצים mediaserver על ידי OMX::allocateBuffer ומשמשים במהלך הפענוח באותו תהליך, כפי שמוצג להלן:

איור 2. אנדרואיד 6.0 והקצאת מאגר נמוך יותר בשרת מדיה.

באנדרואיד 7.0, תהליך הקצאת המאגר השתנה למנגנון חדש המספק גמישות תוך מזעור ההשפעה על יישומים קיימים. עם ערימות MediaDrm ו- MediaCrypto בתהליך ה- mediadrmserver החדש, מאגרים מוקצים בצורה שונה והספקים חייבים לעדכן את נקודות האחיזה המאובטחות של המאגר, כך שניתן יהיה להעבירן על פני מקשר כאשר MediaCodec מפעיל פעולת פענוח ב- MediaCrypto .

איור 3. הקצאת מאגר של אנדרואיד 7.0 ומעלה בשרת מדיה.

שימוש בידיות מקוריות

ה- OMX::allocateBuffer חייב להחזיר מצביע למבנה native_handle , המכיל מתארי קבצים (FDs) ונתונים שלמים נוספים. ל- native_handle יש את כל היתרונות של שימוש ב-FDs, לרבות תמיכת קלסרים קיימת עבור סריאליזציה/deserialization, תוך מתן גמישות רבה יותר לספקים שאינם משתמשים כעת ב-FDs.

השתמש native_handle_create() כדי להקצות את הידית המקורית. קוד המסגרת לוקח בעלות על מבנה ה- native_handle שהוקצה ואחראי לשחרור משאבים הן בתהליך שבו ה- native_handle מוקצה במקור והן בתהליך שבו הוא מופץ בסידריאל. המסגרת משחררת נקודות עזר מקוריות עם native_handle_close() ואחריו native_handle_delete() /מבטלת את ה- native_handle באמצעות Parcel::writeNativeHandle()/readNativeHandle() .

ספקי SoC שמשתמשים ב-FDs כדי לייצג מאגרים מאובטחים יכולים לאכלס את ה-FD ב- native_handle עם ה-FD שלהם. ספקים שאינם משתמשים ב-FD יכולים לייצג מאגרים מאובטחים באמצעות שדות נוספים ב- native_buffer .

הגדרת מיקום פענוח

על הספקים לעדכן את שיטת הפענוח של OEMCrypto הפועלת על ה- native_handle כדי לבצע פעולות ספציפיות לספק הנחוצות כדי להפוך את ה- native_handle במרחב התהליך החדש (שינויים כוללים בדרך כלל עדכונים לספריות OEMCrypto).

מכיוון ש- allocateBuffer היא פעולת OMX סטנדרטית, אנדרואיד 7.0 כוללת תוסף OMX חדש ( OMX.google.android.index.allocateNativeHandle ) לשאילתה לתמיכה זו וקריאה ל- OMX_SetParameter למימוש OMX שעליו להשתמש בנקודות אחיזה מקוריות.