GKI 16-6.12 android-mainline errata

इस पेज पर, android-mainline में मिली अहम समस्याओं और बग को ठीक करने के बारे में बताया गया है. ये समस्याएं और बग, पार्टनर के लिए अहम हो सकते हैं.

15 नवंबर, 2024

  • android-mainline और android16-6.12 के लिए, Clang को 19.0.1 पर अपडेट किया गया है

    • खास जानकारी: Clang के नए वर्शन में, ऐरे के लिए बाउंड सैनिटाइज़र की सुविधा जोड़ी गई है. इसमें ऐरे का साइज़, __counted_by एट्रिब्यूट का इस्तेमाल करके ऐरे से लिंक किए गए अलग वैरिएबल में सेव किया जाता है. अगर ऐरे का साइज़ सही तरीके से अपडेट नहीं किया जाता है, तो इस सुविधा की वजह से कर्नल पैनिक हो सकता है. गड़बड़ी का मैसेज इस तरह दिखता है:
    UBSAN: array-index-out-of-bounds in common/net/wireless/nl80211.c
    index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]')
    
    • जानकारी: बाउंड्स सैनिटाइज़र, कर्नल की इंटिग्रिटी को सुरक्षित रखने के लिए ज़रूरी है. यह कर्नल के बाहर के ऐक्सेस का पता लगाता है. CONFIG_UBSAN_TRAP चालू होने पर, बाउंड सैनिटाइज़र को कोई भी गड़बड़ी मिलने पर, कर्नल पैनिक ट्रिगर हो जाता है.

      • बाउंड्री सैनिटाइज़र का पिछला वर्शन, सिर्फ़ तय साइज़ वाले ऐरे की जांच करता था. साथ ही, वह डाइनैमिक तरीके से असाइन किए गए ऐरे की जांच नहीं कर पाता था. नया वर्शन, रनटाइम के दौरान ऐरे की सीमाओं का पता लगाने के लिए __counted_by एट्रिब्यूट का इस्तेमाल करता है. साथ ही, यह सीमाओं से बाहर के ऐक्सेस के ज़्यादा मामलों का पता लगाता है. हालांकि, कुछ मामलों में साइज़ वैरिएबल सेट होने से पहले ही ऐरे को ऐक्सेस कर लिया जाता है. इससे बाउंड्री सैनिटाइज़र ट्रिगर हो जाता है और कर्नल पैनिक की समस्या आ जाती है. इस समस्या को ठीक करने के लिए, मेमोरी को ऐलोकेट करने के तुरंत बाद, ऐरे का साइज़ सेट करें. इसके बारे में aosp/3343204 में बताया गया है.
    • CONFIG_UBSAN_SIGNED_WRAP के बारे में जानकारी: Clang का नया वर्शन, -fwrapv कंपाइलर फ़्लैग के बावजूद, साइंड पूर्णांक ओवरफ़्लो और अंडरफ़्लो को सैनिटाइज़ करता है. -fwrapv फ़्लैग को इस तरह से डिज़ाइन किया गया है कि यह साइंड पूर्णांकों को, दो के पूरक वाले अनसाइंड पूर्णांकों के तौर पर ट्रीट करता है. इसमें ओवरफ़्लो के बारे में बताया गया होता है.

      • Linux कर्नल में साइंड पूर्णांक ओवरफ़्लो को सैनिटाइज़ करने से, गड़बड़ियों का पता लगाने में मदद मिल सकती है. हालांकि, ऐसे उदाहरण भी हैं जहां ओवरफ़्लो जान-बूझकर किया जाता है. उदाहरण के लिए, atomic_long_t के साथ. इस वजह से, CONFIG_UBSAN_SIGNED_WRAP को बंद कर दिया गया है, ताकि UBSAN सिर्फ़ बाउंड सैनिटाइज़र के तौर पर काम कर सके.
    • CONFIG_UBSAN_TRAP के बारे में जानकारी: UBSAN को इस तरह से कॉन्फ़िगर किया जाता है कि जब भी उसे कोई समस्या दिखे, तो वह कर्नेल पैनिक को ट्रिगर कर दे. ऐसा कर्नेल की इंटिग्रिटी को सुरक्षित रखने के लिए किया जाता है. हालांकि, हमने इस सुविधा को 23 अक्टूबर से 12 नवंबर तक बंद कर दिया था. हमने ऐसा इसलिए किया, ताकि हम __counted_by से जुड़ी समस्याओं को ठीक करते समय, कंपाइलर अपडेट को अनब्लॉक कर सकें.

1 नवंबर, 2024

  • Linux 6.12-rc4 लैंडिंग
    • खास जानकारी: CONFIG_OF_DYNAMIC से खराब ड्राइवर के लिए गंभीर रिग्रेशन हो सकते हैं.
    • जानकारी: Linux 6.12-rc1 को android-mainline में मर्ज करते समय, हमें आउट-ऑफ़-ट्री ड्राइवर लोड न होने से जुड़ी समस्याएं मिलीं. ड्राइवर से जुड़ी गड़बड़ियों का पता लगाने वाले बदलाव की पहचान कमिट 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") के तौर पर की गई है. हमने इसे कुछ समय के लिए aosp/3287735 में पहले जैसा कर दिया है. बदलाव करने पर CONFIG_OF_OVERLAY चुना जाता है. इससे CONFIG_OF_DYNAMIC चुना जाता है. !OF_DYNAMIC की मदद से, of_node_get() और of_node_put() पर रेफ़रंस काउंटिंग की सुविधा बंद हो जाती है, क्योंकि इन्हें noops के तौर पर लागू किया जाता है. OF_DYNAMIC को फिर से चालू करने पर, ड्राइवर में ऐसी समस्याएं दिखती हैं जिनमें struct device_node के लिए रेफ़रंस-काउंटिंग को गलत तरीके से लागू किया गया है. इससे कई तरह की गड़बड़ियां होती हैं. जैसे, मेमोरी करप्शन, फ़्री की गई मेमोरी को इस्तेमाल करने की गड़बड़ी, और मेमोरी लीक.
    • ओएफ़ पार्सिंग से जुड़े सभी एपीआई के इस्तेमाल की जांच की जानी चाहिए. यहां दी गई सूची में कुछ ही उदाहरण शामिल हैं, लेकिन इनमें वे मामले शामिल हैं जिन पर हम नज़र रख रहे हैं:
      • बिना पासवर्ड के पुष्टि करने की सुविधा (यूएएफ़) का इस्तेमाल करना:
        • एक ही device_node आर्ग्युमेंट का फिर से इस्तेमाल करना: ये फ़ंक्शन, दिए गए नोड पर of_node_put() को कॉल करते हैं. इसलिए, इन्हें कॉल करने से पहले of_node_get() को जोड़ने की ज़रूरत पड़ सकती है. उदाहरण के लिए, जब एक ही नोड को आर्ग्युमेंट के तौर पर बार-बार कॉल किया जाता है:
          • of_find_compatible_node()
          • of_find_node_by_name()
          • of_find_node_by_path()
          • of_find_node_by_type()
          • of_get_next_cpu_node()
          • of_get_next_parent()
          • of_get_next_child()
          • of_get_next_available_child()
          • of_get_next_reserved_child()
          • of_find_node_with_property()
          • of_find_matching_node_and_match()
        • कुछ लूप से किसी भी तरह से बाहर निकलने के बाद device_node का इस्तेमाल करना:
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • device_node से char * प्रॉपर्टी के डायरेक्ट पॉइंटर को बनाए रखना. उदाहरण के लिए, इनका इस्तेमाल करना:
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • मेमोरी लीक:
        • device_node को पाना और उसे अनरेफ़ करना (of_node_put()) भूल जाना. इनसे मिले नोड को किसी समय पर फ़्री करना ज़रूरी है:
          • of_find_compatible_node()
          • of_find_node_by_name()
          • of_find_node_by_path()
          • of_find_node_by_type()
          • of_find_node_by_phandle()
          • of_parse_phandle()
          • of_find_node_opts_by_path()
          • of_get_next_cpu_node()
          • of_get_compatible_child()
          • of_get_child_by_name()
          • of_get_parent()
          • of_get_next_parent()
          • of_get_next_child()
          • of_get_next_available_child()
          • of_get_next_reserved_child()
          • of_find_node_with_property()
          • of_find_matching_node_and_match()
      • लूप के किसी इटरेशन से device_node को सेव करना. अगर आपको इनमें से किसी लूप से बाहर निकलना है, तो आपको किसी पॉइंट पर बाकी रेफ़रंस को छोड़ना होगा:
        • for_each_available_child_of_node()
        • for_each_child_of_node()
        • for_each_node_by_type()
        • for_each_compatible_node()
        • of_for_each_phandle()
    • Linux 6.12-rc4 पर स्विच करते समय, पहले बताए गए बदलाव को वापस लाया गया था aosp/3315251. इससे CONFIG_OF_DYNAMIC सुविधा फिर से चालू हो गई और हो सकता है कि ड्राइवर में गड़बड़ी हो.