डिवाइस सुरक्षा में सुधार करने के लिए, एंड्रॉइड 7.0 मोनोलिथिक mediaserver
प्रक्रिया को कई प्रक्रियाओं में विभाजित करता है, जिसमें अनुमतियां और क्षमताएं केवल प्रत्येक प्रक्रिया के लिए आवश्यक होती हैं। ये परिवर्तन मीडिया ढांचे की सुरक्षा कमजोरियों को कम करते हैं:
- AV पाइपलाइन घटकों को ऐप-विशिष्ट सैंडबॉक्स वाली प्रक्रियाओं में विभाजित करना।
- अद्यतन करने योग्य मीडिया घटकों (एक्सट्रैक्टर्स, कोडेक्स, आदि) को सक्षम करना।
ये परिवर्तन अंतिम उपयोगकर्ताओं के लिए सुरक्षा में भी सुधार करते हैं, अधिकांश मीडिया-संबंधित सुरक्षा कमजोरियों की गंभीरता को कम करके, अंतिम उपयोगकर्ता उपकरणों और डेटा को सुरक्षित रखते हुए।
ओईएम और एसओसी विक्रेताओं को अपने एचएएल और ढांचे में बदलाव को अपडेट करने की जरूरत है ताकि उन्हें नए आर्किटेक्चर के साथ संगत बनाया जा सके। विशेष रूप से, क्योंकि विक्रेता द्वारा प्रदान किया गया एंड्रॉइड कोड अक्सर मानता है कि सब कुछ एक ही प्रक्रिया में चलता है, विक्रेताओं को अपने कोड को मूल हैंडल ( native_handle
) के आसपास पास करने के लिए अपडेट करना होगा, जिसका अर्थ सभी प्रक्रियाओं में है। मीडिया हार्डनिंग से संबंधित परिवर्तनों के संदर्भ कार्यान्वयन के लिए, frameworks/av
और frameworks/native
देखें।
वास्तु परिवर्तन
एंड्रॉइड के पिछले संस्करणों में बहुत अधिक अनुमतियों (कैमरा एक्सेस, ऑडियो एक्सेस, वीडियो ड्राइवर एक्सेस, फ़ाइल एक्सेस, नेटवर्क एक्सेस, आदि) के साथ एक एकल, मोनोलिथिक mediaserver
प्रक्रिया का उपयोग किया गया था। एंड्रॉइड 7.0 mediaserver
प्रक्रिया को कई नई प्रक्रियाओं में विभाजित करता है, जिनमें से प्रत्येक को अनुमतियों के बहुत छोटे सेट की आवश्यकता होती है:
चित्र 1. मीडियासर्वर सख्त करने के लिए आर्किटेक्चर परिवर्तन
यह नया आर्किटेक्चर सुनिश्चित करता है कि भले ही किसी प्रक्रिया से समझौता किया गया हो, दुर्भावनापूर्ण कोड के पास मीडियासर्वर द्वारा पहले से रखी गई अनुमतियों के पूर्ण सेट तक पहुंच नहीं है। प्रक्रियाएं SElinux और seccomp नीतियों द्वारा प्रतिबंधित हैं।
नोट: विक्रेता निर्भरता के कारण, कुछ कोडेक अभी भी mediaserver
में चलते हैं और परिणामस्वरूप mediaserver
को आवश्यकता से अधिक अनुमति देते हैं। विशेष रूप से, वाइडवाइन क्लासिक Android 7.0 के लिए mediaserver
में चलना जारी रखता है।
मीडियासर्वर बदलता है
एंड्रॉइड 7.0 में, प्लेबैक और रिकॉर्डिंग चलाने के लिए mediaserver
प्रक्रिया मौजूद है, उदाहरण के लिए घटकों और प्रक्रियाओं के बीच बफर को पास करना और सिंक्रनाइज़ करना। प्रक्रियाएं मानक बाइंडर तंत्र के माध्यम से संचार करती हैं।
एक मानक स्थानीय फ़ाइल प्लेबैक सत्र में, एप्लिकेशन एक फ़ाइल डिस्क्रिप्टर (FD) को mediaserver
(आमतौर पर MediaPlayer Java API के माध्यम से) और mediaserver
को पास करता है:
- FD को एक बाइंडर डेटासोर्स ऑब्जेक्ट में लपेटता है जो एक्स्ट्रेक्टर प्रक्रिया को पास किया जाता है, जो बाइंडर IPC का उपयोग करके फ़ाइल से पढ़ने के लिए इसका उपयोग करता है। (मीडिया एक्सट्रैक्टर को एफडी नहीं मिलती है, लेकिन इसके बजाय बाइंडर डेटा प्राप्त करने के लिए
mediaserver
को वापस कॉल करता है।) - फ़ाइल की जांच करता है, फ़ाइल प्रकार (जैसे MP3Extractor, या MPEG4Extractor) के लिए उपयुक्त एक्सट्रैक्टर बनाता है, और
mediaserver
प्रक्रिया के लिए एक्सट्रैक्टर के लिए एक बाइंडर इंटरफ़ेस देता है। - फ़ाइल में डेटा के प्रकार (जैसे MP3 या H.264 डेटा) को निर्धारित करने के लिए बाइंडर IPC को एक्सट्रैक्टर को कॉल करता है।
- आवश्यक प्रकार के कोडेक्स बनाने के लिए
mediacodec
प्रक्रिया में कॉल करें; इन कोडेक्स के लिए बाइंडर इंटरफेस प्राप्त करता है। - एन्कोडेड नमूनों को पढ़ने के लिए एक्सट्रैक्टर को बार-बार बाइंडर आईपीसी कॉल करता है, डिकोडिंग के लिए
mediacodec
प्रक्रिया में एन्कोडेड डेटा भेजने के लिए बाइंडर आईपीसी का उपयोग करता है, और डीकोडेड डेटा प्राप्त करता है।
कुछ उपयोग के मामलों में, कोई कोडेक शामिल नहीं है (जैसे एक ऑफलोडेड प्लेबैक जहां एन्कोडेड डेटा सीधे आउटपुट डिवाइस पर भेजा जाता है), या कोडेक डीकोड किए गए डेटा को सीधे डिकोड किए गए डेटा (वीडियो प्लेबैक) के बफर को वापस करने के बजाय डीकोड किए गए डेटा को प्रस्तुत कर सकता है।
MediaCodecसेवा परिवर्तन
कोडेक सेवा वह जगह है जहां एन्कोडर और डिकोडर रहते हैं। विक्रेता निर्भरता के कारण, सभी कोडेक अभी तक कोडेक प्रक्रिया में नहीं रहते हैं। एंड्रॉइड 7.0 में:
- गैर-सुरक्षित डिकोडर और सॉफ़्टवेयर एन्कोडर कोडेक प्रक्रिया में रहते हैं।
- सुरक्षित डिकोडर और हार्डवेयर एन्कोडर
mediaserver
(अपरिवर्तित) में रहते हैं।
एक एप्लिकेशन (या मीडियासर्वर) आवश्यक प्रकार का कोडेक बनाने के लिए कोडेक प्रक्रिया को कॉल करता है, फिर उस कोडेक को एन्कोडेड डेटा में पास करने और डिकोड किए गए डेटा (डिकोडिंग के लिए) को पुनः प्राप्त करने या डिकोड किए गए डेटा में पास करने और एन्कोडेड डेटा (एन्कोडिंग के लिए) को पुनः प्राप्त करने के लिए कहता है। . कोडेक्स से डेटा ट्रांसफर पहले से ही साझा मेमोरी का उपयोग करता है, ताकि प्रक्रिया अपरिवर्तित रहे।
MediaDrmServer परिवर्तन
DRM सर्वर का उपयोग DRM-संरक्षित सामग्री को चलाते समय किया जाता है, जैसे कि Google Play - मूवी में मूवी। यह एन्क्रिप्टेड डेटा को सुरक्षित तरीके से डिक्रिप्ट करने का काम करता है, और इस तरह प्रमाणपत्र और कुंजी भंडारण और अन्य संवेदनशील घटकों तक पहुंच है। विक्रेता निर्भरता के कारण, अभी तक सभी मामलों में DRM प्रक्रिया का उपयोग नहीं किया गया है।
ऑडियो सर्वर बदलता है
ऑडियो सर्वर प्रक्रिया ऑडियो से संबंधित घटकों को होस्ट करती है जैसे ऑडियो इनपुट और आउटपुट, नीति प्रबंधक सेवा जो ऑडियो रूटिंग निर्धारित करती है, और एफएम रेडियो सेवा। ऑडियो परिवर्तन और कार्यान्वयन मार्गदर्शन के विवरण के लिए, ऑडियो लागू करना देखें।
कैमरा सर्वर बदलता है
कैमरा सर्वर कैमरे को नियंत्रित करता है और कैमरे से वीडियो फ्रेम प्राप्त करने के लिए वीडियो रिकॉर्ड करते समय उपयोग किया जाता है और फिर उन्हें आगे के संचालन के लिए mediaserver
को पास कर दिया जाता है। कैमरासेवर परिवर्तनों के लिए परिवर्तनों और कार्यान्वयन मार्गदर्शन के विवरण के लिए, कैमरा फ्रेमवर्क हार्डनिंग देखें।
एक्सट्रैक्टरसेवा परिवर्तन
एक्सट्रैक्टर सेवा एक्सट्रैक्टर्स , घटकों को होस्ट करती है जो मीडिया फ्रेमवर्क द्वारा समर्थित विभिन्न फ़ाइल स्वरूपों को पार्स करते हैं। एक्सट्रैक्टर सेवा सभी सेवाओं में सबसे कम विशेषाधिकार प्राप्त है - यह एफडी नहीं पढ़ सकती है, इसलिए इसके बजाय यह फाइलों तक पहुंचने के लिए एक बाइंडर इंटरफेस (प्रत्येक प्लेबैक सत्र mediaserver for
द्वारा प्रदान की गई) पर कॉल करता है।
एक एप्लिकेशन (या mediaserver
) एक IMediaExtractor
प्राप्त करने के लिए एक्सट्रैक्टर प्रक्रिया को कॉल करता है, उस IMediaExtractor
को फ़ाइल में निहित ट्रैक के लिए IMediaSources
प्राप्त करने के लिए कॉल करता है, और फिर उनसे डेटा पढ़ने के लिए IMediaSources
को कॉल करता है।
प्रक्रियाओं के बीच डेटा स्थानांतरित करने के लिए, एप्लिकेशन (या mediaserver
) में बाइंडर लेनदेन के हिस्से के रूप में उत्तर-पार्सल में डेटा शामिल होता है या साझा मेमोरी का उपयोग करता है:
- साझा मेमोरी का उपयोग करने के लिए साझा मेमोरी को रिलीज़ करने के लिए एक अतिरिक्त बाइंडर कॉल की आवश्यकता होती है, लेकिन यह तेज़ होती है और बड़े बफ़र्स के लिए कम शक्ति का उपयोग करती है।
- इन-पार्सल का उपयोग करने के लिए अतिरिक्त प्रतिलिपि की आवश्यकता होती है, लेकिन यह तेज़ है और 64KB से छोटे बफ़र्स के लिए कम शक्ति का उपयोग करता है।
कार्यान्वयन
MediaDrm
और MediaCrypto
घटकों को नई mediadrmserver
प्रक्रिया में ले जाने का समर्थन करने के लिए, विक्रेताओं को प्रक्रियाओं के बीच बफ़र्स को साझा करने की अनुमति देने के लिए सुरक्षित बफ़र्स के लिए आवंटन विधि को बदलना होगा।
पिछले Android रिलीज़ में, सुरक्षित बफ़र्स को OMX::allocateBuffer
द्वारा mediaserver
में आवंटित किया जाता है और उसी प्रक्रिया में डिक्रिप्शन के दौरान उपयोग किया जाता है, जैसा कि नीचे दिखाया गया है:
चित्र 2. एंड्रॉइड 6.0 और मीडियासर्वर में कम बफर आवंटन।
एंड्रॉइड 7.0 में, बफर आवंटन प्रक्रिया एक नए तंत्र में बदल गई है जो मौजूदा कार्यान्वयन पर प्रभाव को कम करते हुए लचीलापन प्रदान करती है। नई mediadrmserver
प्रक्रिया में MediaDrm
और MediaCrypto
स्टैक के साथ, बफ़र्स को अलग-अलग तरीके से आवंटित किया जाता है और विक्रेताओं को सुरक्षित बफ़र हैंडल को अपडेट करना चाहिए ताकि MediaCodec
MediaCrypto
पर डिक्रिप्ट ऑपरेशन को आमंत्रित करने पर उन्हें बाइंडर में ले जाया जा सके।
चित्रा 3. एंड्रॉइड 7.0 और मीडियासर्वर में उच्च बफर आवंटन।
देशी हैंडल का उपयोग करना
OMX::allocateBuffer
को एक native_handle
संरचना में एक पॉइंटर लौटाना चाहिए, जिसमें फ़ाइल डिस्क्रिप्टर (FD) और अतिरिक्त पूर्णांक डेटा होता है। एक native_handle
में एफडी का उपयोग करने के सभी फायदे हैं, जिसमें क्रमांकन/डिसेरिएलाइज़ेशन के लिए मौजूदा बाइंडर समर्थन शामिल है, जबकि वेंडरों के लिए अधिक लचीलेपन की अनुमति देता है जो वर्तमान में एफडी का उपयोग नहीं करते हैं।
देशी हैंडल आवंटित करने के लिए native_handle_create()
का प्रयोग करें। फ्रेमवर्क कोड आवंटित native_handle
स्ट्रक्चर का स्वामित्व लेता है और दोनों प्रक्रियाओं में संसाधनों को जारी करने के लिए जिम्मेदार होता है जहां native_handle
मूल रूप से आवंटित किया जाता है और उस प्रक्रिया में जहां इसे डिसेरिएलाइज़ किया जाता है। फ्रेमवर्क नेटिव_हैंडल_क्लोज़ () के साथ native_handle_close()
के साथ नेटिव हैंडल जारी करता है और Parcel::writeNativeHandle()/readNativeHandle()
native_handle_delete()
उपयोग करके native_handle
को क्रमबद्ध/deserializes करता है।
एसओसी विक्रेता जो सुरक्षित बफर का प्रतिनिधित्व करने के लिए एफडी का उपयोग करते हैं, वे अपने एफडी के साथ एफडी को native_handle
में पॉप्युलेट कर सकते हैं। जो विक्रेता FD का उपयोग नहीं करते हैं, वे native_buffer
में अतिरिक्त फ़ील्ड का उपयोग करके सुरक्षित बफ़र्स का प्रतिनिधित्व कर सकते हैं।
डिक्रिप्शन स्थान सेट करना
विक्रेताओं को OEMCrypto डिक्रिप्ट विधि को अद्यतन करना चाहिए जो कि नई प्रक्रिया स्थान में native_handle
को प्रयोग करने योग्य बनाने के लिए आवश्यक कोई भी विक्रेता-विशिष्ट संचालन करने के लिए native_handle
पर संचालित होता है (परिवर्तनों में आमतौर पर OEMCrypto लाइब्रेरी में अपडेट शामिल होते हैं)।
चूंकि allocateBuffer
एक मानक ओएमएक्स ऑपरेशन है, एंड्रॉइड 7.0 में इस समर्थन के लिए OMX_SetParameter
करने के लिए एक नया ओएमएक्स एक्सटेंशन ( OMX.google.android.index.allocateNativeHandle
.