मीडिया ढाँचा सख्त हो रहा है

डिवाइस सुरक्षा में सुधार करने के लिए, एंड्रॉइड 7.0 मोनोलिथिक mediaserver प्रक्रिया को कई प्रक्रियाओं में विभाजित करता है, जिसमें अनुमतियाँ और क्षमताएं केवल प्रत्येक प्रक्रिया के लिए आवश्यक तक ही सीमित होती हैं। ये परिवर्तन मीडिया फ्रेमवर्क सुरक्षा कमजोरियों को कम करते हैं:

  • एवी पाइपलाइन घटकों को ऐप-विशिष्ट सैंडबॉक्स प्रक्रियाओं में विभाजित करना।
  • अद्यतन करने योग्य मीडिया घटकों (एक्सट्रैक्टर्स, कोडेक्स, आदि) को सक्षम करना।

ये परिवर्तन अधिकांश मीडिया-संबंधित सुरक्षा कमजोरियों की गंभीरता को कम करके, अंतिम उपयोगकर्ता उपकरणों और डेटा को सुरक्षित रखते हुए अंतिम उपयोगकर्ताओं के लिए सुरक्षा में सुधार करते हैं।

ओईएम और एसओसी विक्रेताओं को अपने एचएएल और फ्रेमवर्क परिवर्तनों को नए आर्किटेक्चर के साथ संगत बनाने के लिए अद्यतन करने की आवश्यकता है। विशेष रूप से, क्योंकि विक्रेता द्वारा प्रदत्त एंड्रॉइड कोड अक्सर मानता है कि सब कुछ एक ही प्रक्रिया में चलता है, विक्रेताओं को अपने कोड को देशी हैंडल ( native_handle ) से गुजरने के लिए अपडेट करना होगा, जिसका सभी प्रक्रियाओं में अर्थ होता है। मीडिया हार्डनिंग से संबंधित परिवर्तनों के संदर्भ कार्यान्वयन के लिए, frameworks/av और frameworks/native देखें।

वास्तु परिवर्तन

एंड्रॉइड के पिछले संस्करणों में कई अनुमतियों (कैमरा एक्सेस, ऑडियो एक्सेस, वीडियो ड्राइवर एक्सेस, फ़ाइल एक्सेस, नेटवर्क एक्सेस इत्यादि) के साथ एकल, मोनोलिथिक mediaserver प्रक्रिया का उपयोग किया गया था। एंड्रॉइड 7.0 mediaserver प्रक्रिया को कई नई प्रक्रियाओं में विभाजित करता है, जिनमें से प्रत्येक को अनुमतियों के बहुत छोटे सेट की आवश्यकता होती है:

मीडियासर्वर सख्त होना

चित्र 1. मीडियासर्वर हार्डनिंग के लिए आर्किटेक्चर परिवर्तन

यह नया आर्किटेक्चर यह सुनिश्चित करता है कि भले ही किसी प्रक्रिया से समझौता किया गया हो, दुर्भावनापूर्ण कोड की mediaserver द्वारा पहले से रखी गई अनुमतियों के पूर्ण सेट तक पहुंच नहीं है। प्रक्रियाएँ SElinux और seccomp नीतियों द्वारा प्रतिबंधित हैं।

नोट: विक्रेता निर्भरता के कारण, कुछ कोडेक्स अभी भी mediaserver में चलते हैं और परिणामस्वरूप mediaserver आवश्यकता से अधिक अनुमतियाँ प्रदान करते हैं। विशेष रूप से, वाइडवाइन क्लासिक एंड्रॉइड 7.0 के लिए mediaserver में चलता रहता है।

मीडियासर्वर बदलता है

एंड्रॉइड 7.0 में, प्लेबैक और रिकॉर्डिंग को चलाने के लिए mediaserver प्रक्रिया मौजूद है, उदाहरण के लिए घटकों और प्रक्रियाओं के बीच बफ़र्स को पास करना और सिंक्रनाइज़ करना। प्रक्रियाएँ मानक बाइंडर तंत्र के माध्यम से संचार करती हैं।

एक मानक स्थानीय फ़ाइल प्लेबैक सत्र में, ऐप एक फ़ाइल डिस्क्रिप्टर (एफडी) को mediaserver (आमतौर पर मीडियाप्लेयर जावा एपीआई के माध्यम से) और mediaserver पास करता है:

  1. एफडी को एक बाइंडर डेटासोर्स ऑब्जेक्ट में लपेटता है जिसे एक्सट्रैक्टर प्रक्रिया में भेजा जाता है, जो बाइंडर आईपीसी का उपयोग करके फ़ाइल से पढ़ने के लिए इसका उपयोग करता है। (मीडियाएक्सट्रैक्टर को एफडी नहीं मिलती है, बल्कि वह डेटा प्राप्त करने के लिए बाइंडर को mediaserver पर वापस कॉल करता है।)
  2. फ़ाइल की जांच करता है, फ़ाइल प्रकार (उदाहरण के लिए MP3Extractor, या MPEG4Extractor) के लिए उपयुक्त एक्सट्रैक्टर बनाता है, और mediaserver प्रक्रिया में एक्सट्रैक्टर के लिए एक बाइंडर इंटरफ़ेस लौटाता है।
  3. फ़ाइल में डेटा का प्रकार (जैसे MP3 या H.264 डेटा) निर्धारित करने के लिए एक्सट्रैक्टर को बाइंडर IPC कॉल करता है।
  4. आवश्यक प्रकार के कोडेक्स बनाने के लिए mediacodec प्रक्रिया में कॉल करता है; इन कोडेक्स के लिए बाइंडर इंटरफेस प्राप्त करता है।
  5. एन्कोडेड नमूनों को पढ़ने के लिए एक्सट्रैक्टर को बार-बार बाइंडर आईपीसी कॉल करता है, डिकोडिंग के लिए mediacodec प्रक्रिया में एन्कोडेड डेटा भेजने के लिए बाइंडर आईपीसी का उपयोग करता है, और डिकोडेड डेटा प्राप्त करता है।

कुछ उपयोग मामलों में, कोई कोडेक शामिल नहीं होता है (जैसे कि एक ऑफलोडेड प्लेबैक जहां एन्कोडेड डेटा सीधे आउटपुट डिवाइस पर भेजा जाता है), या कोडेक डिकोड किए गए डेटा (वीडियो प्लेबैक) के बफर को वापस करने के बजाय सीधे डिकोड किए गए डेटा को प्रस्तुत कर सकता है।

MediaCodecService परिवर्तन

कोडेक सेवा वह जगह है जहां एनकोडर और डिकोडर रहते हैं। विक्रेता निर्भरता के कारण, सभी कोडेक्स अभी तक कोडेक प्रक्रिया में नहीं रहते हैं। एंड्रॉइड 7.0 में:

  • गैर-सुरक्षित डिकोडर और सॉफ़्टवेयर एनकोडर कोडेक प्रक्रिया में रहते हैं।
  • सुरक्षित डिकोडर और हार्डवेयर एनकोडर mediaserver (अपरिवर्तित) में रहते हैं।

एक ऐप (या mediaserver ) आवश्यक प्रकार का कोडेक बनाने के लिए कोडेक प्रक्रिया को कॉल करता है, फिर उस कोडेक को एन्कोडेड डेटा को पास करने और डिकोड किए गए डेटा को पुनर्प्राप्त करने के लिए कॉल करता है (डिकोडिंग के लिए) या डिकोड किए गए डेटा को पास करने और एन्कोडेड डेटा को पुनर्प्राप्त करने के लिए (एन्कोडिंग के लिए) . कोडेक्स से डेटा ट्रांसफर पहले से ही साझा मेमोरी का उपयोग करता है, इसलिए यह प्रक्रिया अपरिवर्तित है।

MediaDrmServer बदलता है

DRM सर्वर का उपयोग DRM-संरक्षित सामग्री, जैसे Google Play Movies में फिल्में चलाते समय किया जाता है। यह एन्क्रिप्टेड डेटा को सुरक्षित तरीके से डिक्रिप्ट करने का काम संभालता है, और इस तरह प्रमाणपत्र और कुंजी भंडारण और अन्य संवेदनशील घटकों तक इसकी पहुंच होती है। विक्रेता निर्भरता के कारण, DRM प्रक्रिया का उपयोग अभी तक सभी मामलों में नहीं किया जाता है।

ऑडियोसर्वर बदलता है

ऑडियोसर्वर प्रक्रिया ऑडियो से संबंधित घटकों जैसे ऑडियो इनपुट और आउटपुट, पॉलिसी मैनेजर सेवा जो ऑडियो रूटिंग निर्धारित करती है, और एफएम रेडियो सेवा को होस्ट करती है। ऑडियो परिवर्तन और कार्यान्वयन मार्गदर्शन के विवरण के लिए, ऑडियो लागू करें देखें।

कैमरासर्वर बदलता है

कैमरासर्वर कैमरे को नियंत्रित करता है और इसका उपयोग वीडियो रिकॉर्ड करते समय कैमरे से वीडियो फ्रेम प्राप्त करने और फिर उन्हें आगे की हैंडलिंग के लिए mediaserver तक भेजने के लिए किया जाता है। कैमरासर्वर परिवर्तनों के लिए परिवर्तनों और कार्यान्वयन मार्गदर्शन के विवरण के लिए, कैमरा फ्रेमवर्क हार्डनिंग देखें।

एक्सट्रैक्टरसेवा में परिवर्तन

एक्सट्रैक्टर सेवा एक्सट्रैक्टर्स , घटकों को होस्ट करती है जो मीडिया फ्रेमवर्क द्वारा समर्थित विभिन्न फ़ाइल स्वरूपों को पार्स करती है। एक्सट्रैक्टर सेवा सभी सेवाओं में सबसे कम विशेषाधिकार प्राप्त है - यह एफडी नहीं पढ़ सकती है इसलिए इसके बजाय यह फ़ाइलों तक पहुंचने के लिए बाइंडर इंटरफ़ेस (प्रत्येक प्लेबैक सत्र mediaserver for द्वारा इसे प्रदान किया जाता है) पर कॉल करती है।

एक ऐप (या mediaserver ) IMediaExtractor प्राप्त करने के लिए एक्सट्रैक्टर प्रक्रिया को कॉल करता है, फ़ाइल में निहित ट्रैक के लिए IMediaSources प्राप्त करने के लिए उस IMediaExtractor कॉल करता है, और फिर उनसे डेटा पढ़ने के लिए IMediaSources कॉल करता है।

प्रक्रियाओं के बीच डेटा स्थानांतरित करने के लिए, ऐप (या mediaserver ) बाइंडर लेनदेन के हिस्से के रूप में उत्तर-पार्सल में डेटा शामिल करता है या साझा मेमोरी का उपयोग करता है:

  • साझा मेमोरी का उपयोग करने के लिए साझा मेमोरी को रिलीज़ करने के लिए एक अतिरिक्त बाइंडर कॉल की आवश्यकता होती है, लेकिन यह तेज़ है और बड़े बफ़र्स के लिए कम बिजली का उपयोग करता है।
  • इन-पार्सल का उपयोग करने के लिए अतिरिक्त प्रतिलिपि की आवश्यकता होती है, लेकिन यह तेज़ है और 64KB से छोटे बफ़र्स के लिए कम बिजली का उपयोग करता है।

कार्यान्वयन

MediaDrm और MediaCrypto घटकों को नई mediadrmserver प्रक्रिया में ले जाने का समर्थन करने के लिए, विक्रेताओं को सुरक्षित बफ़र्स के लिए आवंटन विधि को बदलना होगा ताकि बफ़र्स को प्रक्रियाओं के बीच साझा किया जा सके।

पिछले एंड्रॉइड रिलीज़ में, सुरक्षित बफ़र्स को OMX::allocateBuffer द्वारा mediaserver में आवंटित किया जाता है और उसी प्रक्रिया में डिक्रिप्शन के दौरान उपयोग किया जाता है, जैसा कि नीचे दिखाया गया है:

चित्र 2. एंड्रॉइड 6.0 और मीडियासर्वर में निचला बफर आवंटन।

एंड्रॉइड 7.0 में, बफर आवंटन प्रक्रिया एक नए तंत्र में बदल गई है जो मौजूदा कार्यान्वयन पर प्रभाव को कम करते हुए लचीलापन प्रदान करती है। नई mediadrmserver प्रक्रिया में MediaDrm और MediaCrypto स्टैक के साथ, बफ़र्स को अलग तरह से आवंटित किया जाता है और विक्रेताओं को सुरक्षित बफ़र हैंडल को अपडेट करना होगा ताकि जब MediaCodec MediaCrypto पर एक डिक्रिप्ट ऑपरेशन शुरू करता है तो उन्हें बाइंडर में ले जाया जा सके।

चित्र 3. एंड्रॉइड 7.0 और मीडियासर्वर में उच्चतर बफर आवंटन।

देशी हैंडल का प्रयोग करें

OMX::allocateBuffer एक पॉइंटर को native_handle संरचना में वापस करना होगा, जिसमें फ़ाइल डिस्क्रिप्टर (एफडी) और अतिरिक्त पूर्णांक डेटा शामिल है। एक native_handle एफडी का उपयोग करने के सभी फायदे हैं, जिसमें क्रमबद्धता/डिसीरियलाइजेशन के लिए मौजूदा बाइंडर समर्थन शामिल है, जबकि उन विक्रेताओं के लिए अधिक लचीलेपन की अनुमति है जो वर्तमान में एफडी का उपयोग नहीं करते हैं।

नेटिव हैंडल आवंटित करने के लिए native_handle_create() उपयोग करें। फ़्रेमवर्क कोड आवंटित native_handle संरचना का स्वामित्व लेता है और उस प्रक्रिया में संसाधनों को जारी करने के लिए जिम्मेदार है जहां native_handle मूल रूप से आवंटित किया गया है और उस प्रक्रिया में जहां इसे डिसेरिएलाइज़ किया गया है। फ्रेमवर्क native_handle_close() के साथ नेटिव हैंडल जारी करता है और उसके बाद native_handle_delete() जारी करता है और Parcel::writeNativeHandle()/readNativeHandle() उपयोग करके native_handle क्रमबद्ध/deserialize करता है।

एसओसी विक्रेता जो सुरक्षित बफ़र्स का प्रतिनिधित्व करने के लिए एफडी का उपयोग करते हैं, वे एफडी को अपने एफडी के साथ native_handle में भर सकते हैं। जो विक्रेता एफडी का उपयोग नहीं करते हैं, वे native_buffer में अतिरिक्त फ़ील्ड का उपयोग करके सुरक्षित बफ़र्स का प्रतिनिधित्व कर सकते हैं।

डिक्रिप्शन स्थान सेट करें

विक्रेताओं को OEMCrypto डिक्रिप्ट विधि को अपडेट करना होगा जो native_handle पर काम करता है ताकि native_handle नए प्रोसेस स्पेस में उपयोग करने योग्य बनाने के लिए आवश्यक किसी भी विक्रेता-विशिष्ट संचालन को निष्पादित किया जा सके (परिवर्तनों में आमतौर पर OEMCrypto लाइब्रेरीज़ के अपडेट शामिल होते हैं)।

चूंकि allocateBuffer एक मानक OMX ऑपरेशन है, एंड्रॉइड 7.0 में इस समर्थन के लिए क्वेरी करने के लिए एक नया OMX एक्सटेंशन ( OMX.google.android.index.allocateNativeHandle ) और एक OMX_SetParameter कॉल शामिल है जो OMX कार्यान्वयन को सूचित करता है कि इसे मूल हैंडल का उपयोग करना चाहिए।