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

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

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

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

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

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

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

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

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

ארכיטקטורה חדשה זו מבטיחה שגם אם תהליך נפגע, לקוד זדוני אין גישה לסט המלא של ההרשאות שהוחזקו בעבר על ידי mediaserver . תהליכים מוגבלים על ידי מדיניות 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, או MPEG4Extractor), ומחזיר ממשק Binder עבור המחלץ לתהליך mediaserver .
  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 (ללא שינוי).

אפליקציה (או 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. הקצאת מאגר ב-Android 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 שלהם. ספקים שאינם משתמשים ב-FDs יכולים לייצג מאגרים מאובטחים באמצעות שדות נוספים ב- native_buffer .

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

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

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