UndefinedBehaviorSanitizer

UndefinedBehaviorSanitizer (UBSan), कॉम्पाइल के समय इंस्ट्रूमेंटेशन करता है, ताकि अलग-अलग तरह के अनिर्दिष्ट व्यवहार की जांच की जा सके. UBSan, काम करने के तरीके से जुड़े कई बग का पता लगा सकता है. हालांकि, Android इनका पता नहीं लगा सकता:

  • अलाइनमेंट
  • bool
  • bounds
  • enum
  • float-cast-overflow
  • float-divide-by-zero
  • integer-divide-by-zero
  • nonnull-attribute
  • खाली
  • रिटर्न स्टेटमेंट
  • returns-nonnull-attribute
  • shift-base
  • shift-exponent
  • signed-integer-overflow
  • पहुंच में नहीं
  • unsigned-integer-overflow
  • vla-bound

बिना साइन वाला पूर्णांक ओवरफ़्लो, तकनीकी तौर पर अनिर्धारित व्यवहार नहीं है. हालांकि, इसे सैनिटाइज़र में शामिल किया गया है. साथ ही, इसे कई Android मॉड्यूल में इस्तेमाल किया जाता है. इनमें मीडिया सर्वर कॉम्पोनेंट भी शामिल हैं. ऐसा इसलिए किया जाता है, ताकि पूर्णांक ओवरफ़्लो से जुड़ी किसी भी संभावित कमजोरी को खत्म किया जा सके.

लागू करना

Android बिल्ड सिस्टम में, UBSan को दुनिया भर में या स्थानीय तौर पर चालू किया जा सकता है. दुनिया भर में UBSan को चालू करने के लिए, Android.mk में SANITIZE_TARGET सेट करें. हर मॉड्यूल के लेवल पर UBSan को चालू करने के लिए, LOCAL_SANITIZE सेट करें. साथ ही, उन गड़बड़ियों के बारे में बताएं जिन्हें आपको Android.mk में देखना है. उदाहरण के लिए:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0

LOCAL_SRC_FILES:= sanitizer-status.c

LOCAL_MODULE:= sanitizer-status

LOCAL_SANITIZE := alignment bounds null unreachable integer
LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer

include $(BUILD_EXECUTABLE)

और ब्लूप्रिंट (Android.bp) का मिलता-जुलता कॉन्फ़िगरेशन:

cc_binary {

    cflags: [
        "-std=c11",
        "-Wall",
        "-Werror",
        "-O0",
    ],

    srcs: ["sanitizer-status.c"],

    name: "sanitizer-status",

    sanitize: {
        misc_undefined: [
            "alignment",
            "bounds",
            "null",
            "unreachable",
            "integer",
        ],
        diag: {
            misc_undefined: [
                "alignment",
                "bounds",
                "null",
                "unreachable",
                "integer",
            ],
        },
    },

}

UBSan के शॉर्टकट

Android में दो शॉर्टकट, integer और default-ub भी हैं. इनकी मदद से, एक साथ कई सैनिटाइज़र चालू किए जा सकते हैं. integer, integer-divide-by-zero, signed-integer-overflow, और unsigned-integer-overflow को चालू करता है. default-ub, उन जांचों को चालू करता है जिनमें कम से कम कंपाइलर की परफ़ॉर्मेंस से जुड़ी समस्याएं होती हैं: bool, integer-divide-by-zero, return, returns-nonnull-attribute, shift-exponent, unreachable and vla-bound. पूर्णांक की वैल्यू को सुरक्षित करने वाली क्लास का इस्तेमाल, SANITIZE_TARGET और LOCAL_SANITIZE के साथ किया जा सकता है. वहीं, default-ub का इस्तेमाल सिर्फ़ SANITIZE_TARGET के साथ किया जा सकता है.

गड़बड़ी की बेहतर रिपोर्टिंग

Android के डिफ़ॉल्ट UBSan लागू होने पर, कोई तय नहीं किया गया व्यवहार मिलने पर, एक तय फ़ंक्शन को कॉल किया जाता है. डिफ़ॉल्ट रूप से, यह फ़ंक्शन बंद रहता है. हालांकि, अक्टूबर 2016 से Android पर UBSan में एक वैकल्पिक रनटाइम लाइब्रेरी है. इससे गड़बड़ी की ज़्यादा जानकारी मिलती है. इसमें, गड़बड़ी के टाइप, फ़ाइल, और सोर्स कोड लाइन की जानकारी शामिल होती है. पूर्णांक की जांच के साथ गड़बड़ी की रिपोर्टिंग की सुविधा चालू करने के लिए, Android.mk फ़ाइल में यह जोड़ें:

LOCAL_SANITIZE:=integer
LOCAL_SANITIZE_DIAG:=integer

LOCAL_SANITIZE वैल्यू, बिल्ड के दौरान सैनिटाइज़र को चालू करती है. LOCAL_SANITIZE_DIAG, बताए गए सैनिटाइज़र के लिए गड़बड़ी की जानकारी देने वाले मोड को चालू करता है. LOCAL_SANITIZE और LOCAL_SANITIZE_DIAG को अलग-अलग वैल्यू पर सेट किया जा सकता है. हालांकि, LOCAL_SANITIZE में सिर्फ़ वे जांच चालू होती हैं. अगर किसी जांच के बारे में LOCAL_SANITIZE में नहीं बताया गया है, लेकिन LOCAL_SANITIZE_DIAG में बताया गया है, तो जांच चालू नहीं होती और गड़बड़ी की जानकारी देने वाले मैसेज नहीं दिए जाते.

यहां UBSan रनटाइम लाइब्रेरी से मिली जानकारी का उदाहरण दिया गया है:

pixel-xl:/ # sanitizer-status ubsan
sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')

इंटिजर ओवरफ़्लो सैनिटाइज़ेशन

अनचाहे इंटिजर ओवरफ़्लो की वजह से, मेमोरी ऐक्सेस या मेमोरी ऐलोकेशन से जुड़े वैरिएबल में, मेमोरी खराब हो सकती है या जानकारी ज़ाहिर होने की कमज़ोरियां पैदा हो सकती हैं. इस समस्या से निपटने के लिए, हमने Android 7.0 में Clang के UndefinedBehaviorSanitizer (UBSan) के हस्ताक्षर वाले और बिना हस्ताक्षर वाले पूर्णांक के ओवरफ़्लो सैनिटाइज़र जोड़े हैं, ताकि मीडिया फ़्रेमवर्क को ज़्यादा सुरक्षित बनाया जा सके. Android 9 में, हमने ज़्यादा कॉम्पोनेंट को कवर करने के लिए, UBSan को बड़ा किया है. साथ ही, इसके लिए बिल्ड सिस्टम के साथ बेहतर तरीके से काम करने की सुविधा जोड़ी है.

इसे अंकगणितीय ऑपरेशन और निर्देशों के लिए जांच करने के लिए डिज़ाइन किया गया है. इनमें से कुछ निर्देशों से, कैलकुलेशन के दौरान डेटा का ओवरफ़्लो हो सकता है. इसलिए, ओवरफ़्लो होने पर प्रोसेस को सुरक्षित तरीके से बंद करने के लिए, इस सुविधा का इस्तेमाल किया जाता है. ये सैनिटाइज़र, मेमोरी में डेटा गड़बड़ी और जानकारी ज़ाहिर होने से जुड़ी सभी तरह की समस्याओं को कम कर सकते हैं. ऐसा तब होता है, जब इन समस्याओं की मुख्य वजह इंटिजर का ओवरफ़्लो हो. जैसे, Stagefright की मूल समस्या.

उदाहरण और सोर्स

इंटिजर ओवरफ़्लो सैनिटाइज़ेशन (IntSan) सुविधा, कंपाइलर उपलब्ध कराता है. यह सुविधा, कंपाइल करने के दौरान बाइनरी में इंस्ट्रूमेंटेशन जोड़ती है, ताकि अंकगणितीय ओवरफ़्लो का पता लगाया जा सके. यह सुविधा, पूरे प्लैटफ़ॉर्म के अलग-अलग कॉम्पोनेंट में डिफ़ॉल्ट रूप से चालू होती है. उदाहरण के लिए, /platform/external/libnl/Android.bp.

लागू करना

IntSan, UBSan के साइन किए गए और बिना साइन वाले पूर्णांक ओवरफ़्लो सैनिटाइज़र का इस्तेमाल करता है. यह कम करने की सुविधा, हर मॉड्यूल के लेवल पर चालू होती है. इससे Android के अहम कॉम्पोनेंट को सुरक्षित रखने में मदद मिलती है. इसलिए, इसे बंद नहीं किया जाना चाहिए.

हमारा सुझाव है कि आप ज़्यादा कॉम्पोनेंट के लिए, पूर्णांक के ओवरफ़्लो को ठीक करने की सुविधा चालू करें. इसके लिए, खास तौर पर नेटिव कोड या ऐसा नेटिव कोड इस्तेमाल किया जाता है जो उपयोगकर्ता के अविश्वसनीय इनपुट को पार्स करता है. सैनिटाइज़र की परफ़ॉर्मेंस पर थोड़ा असर पड़ता है. यह असर, कोड के इस्तेमाल और अंकगणितीय ऑपरेशन के प्रचलन पर निर्भर करता है. थोड़े ओवरहेड प्रतिशत की उम्मीद करें और देखें कि परफ़ॉर्मेंस पर असर पड़ा है या नहीं.

मेकफ़ाइल में IntSan का इस्तेमाल करना

किसी मेकफ़ाइल में IntSan को चालू करने के लिए, यह जोड़ें:

LOCAL_SANITIZE := integer_overflow
    # Optional features
    LOCAL_SANITIZE_DIAG := integer_overflow
    LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
  • LOCAL_SANITIZE, सैनिटाइज़र की कॉमा से अलग की गई सूची लेता है. इसमें integer_overflow, पहले से पैकेज किए गए विकल्पों का एक सेट होता है. यह सेट, साइन वाले और साइन न वाले अलग-अलग पूर्णांक के ओवरफ़्लो सैनिटाइज़र के लिए होता है. साथ ही, इसमें डिफ़ॉल्ट BLOCKLIST भी होता है.
  • LOCAL_SANITIZE_DIAG, सैनिटाइज़र के लिए गड़बड़ी का पता लगाने वाला मोड चालू करता है. गड़बड़ी की जानकारी देने वाले मोड का इस्तेमाल सिर्फ़ टेस्टिंग के दौरान करें, क्योंकि यह ओवरफ़्लो होने पर प्रोसेस को बंद नहीं करेगा. इससे, गड़बड़ी को कम करने की सुविधा से मिलने वाले सुरक्षा फ़ायदे का पूरी तरह से नुकसान होगा. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.
  • LOCAL_SANITIZE_BLOCKLIST की मदद से, BLOCKLIST फ़ाइल तय की जा सकती है, ताकि फ़ंक्शन और सोर्स फ़ाइलों को साफ़ न किया जा सके. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.

अगर आपको ज़्यादा बारीकी से कंट्रोल करना है, तो एक या दोनों फ़्लैग का इस्तेमाल करके, अलग-अलग सैनिटाइज़र चालू करें:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
    LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

ब्लूप्रिंट फ़ाइलों में IntSan का इस्तेमाल करना

/platform/external/libnl/Android.bp जैसी ब्लूप्रिंट फ़ाइल में, पूर्णांक के ओवरफ़्लो को साफ़ करने की सुविधा चालू करने के लिए, ये जोड़ें:

   sanitize: {
          integer_overflow: true,
          diag: {
              integer_overflow: true,
          },
          BLOCKLIST: "modulename_BLOCKLIST.txt",
       },

मेक फ़ाइलों की तरह ही, integer_overflow प्रॉपर्टी, पहले से पैकेज किए गए विकल्पों का एक सेट है. इसमें, साइन वाले और साइन न किए गए अलग-अलग पूर्णांक के ओवरफ़्लो को ठीक करने वाले टूल के लिए, डिफ़ॉल्ट ब्लॉकलिस्ट शामिल है.

प्रॉपर्टी का diag सेट, सैनिटाइज़र के लिए गड़बड़ी की जानकारी देने वाले मोड को चालू करता है. गड़बड़ी की जानकारी देने वाले मोड का इस्तेमाल सिर्फ़ टेस्टिंग के दौरान करें. गड़बड़ी की जानकारी देने वाला मोड, ओवरफ़्लो होने पर प्रोसेस को बंद नहीं करता. इससे, उपयोगकर्ता के बिल्ड में, कम करने की सुविधा से मिलने वाले सुरक्षा फ़ायदे का पूरी तरह से नुकसान होता है. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.

BLOCKLIST प्रॉपर्टी की मदद से, ब्लॉकलिस्ट फ़ाइल तय की जा सकती है. इससे डेवलपर, फ़ंक्शन और सोर्स फ़ाइलों को साफ़ किए जाने से रोक सकते हैं. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.

सैनिटाइज़र को अलग-अलग चालू करने के लिए, इनका इस्तेमाल करें:

   sanitize: {
          misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
          diag: {
              misc_undefined: ["signed-integer-overflow",
                               "unsigned-integer-overflow",],
          },
          BLOCKLIST: "modulename_BLOCKLIST.txt",
       },

समस्या का हल

अगर नए कॉम्पोनेंट में पूर्णांक के ओवरफ़्लो को साफ़ करने की सुविधा चालू की जा रही है या ऐसी प्लैटफ़ॉर्म लाइब्रेरी का इस्तेमाल किया जा रहा है जिनमें पूर्णांक के ओवरफ़्लो को साफ़ करने की सुविधा है, तो आपको कुछ समस्याएं आ सकती हैं. इन समस्याओं की वजह से, प्रोसेस बीच में रुक सकती है. आपको घटकों की जांच, 'साफ़ करें' सुविधा चालू करके करनी चाहिए, ताकि यह पक्का किया जा सके कि बिना किसी नुकसान के ओवरफ़्लो दिखाए जा सकते हैं.

उपयोगकर्ता के बिल्ड में, डेटा को साफ़ करने की प्रोसेस की वजह से क्रैश होने की जानकारी पाने के लिए, SIGABRT ऐसे क्रैश खोजें जिनमें 'कार्रवाई रोकें' मैसेज दिखते हों. इन मैसेज से पता चलता है कि UBSan ने किसी ओवरफ़्लो का पता लगाया है. जैसे:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
    signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    Abort message: 'ubsan: sub-overflow'

स्टैक ट्रेस में, उस फ़ंक्शन को शामिल करना चाहिए जिसकी वजह से प्रोसेस बंद हुई. हालांकि, ऐसा हो सकता है कि इनलाइन फ़ंक्शन में होने वाले ओवरफ़्लो, स्टैक ट्रेस में न दिखें.

समस्या की मूल वजह को आसानी से पता लगाने के लिए, लाइब्रेरी में डाइग्नोस्टिक्स टूल चालू करें और फिर से गड़बड़ी को ट्रिगर करें. गड़बड़ी की जानकारी देने की सुविधा चालू होने पर, प्रोसेस बंद नहीं होगी. इसके बजाय, यह प्रोसेस जारी रहेगी. प्रोसेस को बीच में न रोकने से, किसी खास प्रोसेस पाथ में, गैर-हानिकारक ओवरफ़्लो की संख्या को बढ़ाने में मदद मिलती है. ऐसा करने के लिए, हर गड़बड़ी को ठीक करने के बाद, प्रोग्राम को फिर से कंपाइल करने की ज़रूरत नहीं होती. गड़बड़ी की जानकारी देने वाला टूल, गड़बड़ी का एक मैसेज दिखाता है. इसमें उस लाइन नंबर और सोर्स फ़ाइल की जानकारी होती है जिसकी वजह से प्रोसेस को रोका गया है:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

गणितीय ऑपरेशन में समस्या का पता चलने के बाद, पक्का करें कि ओवरफ़्लो सही और सही जगह पर हो (जैसे, सुरक्षा पर कोई असर न डालता हो). सैनिटाइज़र के काम न करने की समस्या को ठीक करने के लिए:

  • ओवरफ़्लो से बचने के लिए, कोड को फिर से लिखना (उदाहरण)
  • Clang के __builtin_*_overflow फ़ंक्शन के ज़रिए, साफ़ तौर पर ओवरफ़्लो करना (उदाहरण)
  • no_sanitize एट्रिब्यूट की वैल्यू डालकर, फ़ंक्शन में डेटा को साफ़ करने की सुविधा बंद करना (उदाहरण)
  • BLOCKLIST फ़ाइल की मदद से, किसी फ़ंक्शन या सोर्स फ़ाइल को साफ़ करने की सुविधा बंद करना (उदाहरण)

आपको सबसे सटीक समाधान का इस्तेमाल करना चाहिए. उदाहरण के लिए, अगर किसी बड़े फ़ंक्शन में कई अंकगणितीय ऑपरेशन और एक ओवरफ़्लो ऑपरेशन है, तो पूरे फ़ंक्शन को ब्लॉक किए जाने के बजाय, सिर्फ़ उस ऑपरेशन को फिर से तैयार किया जाना चाहिए.

आम तौर पर, इन पैटर्न की वजह से गैर-हानिकारक ओवरफ़्लो हो सकते हैं:

  • ऐसी असाइनमेंट जिनमें साइन वाले टाइप में असाइन करने से पहले, बिना साइन वाले टाइप में ओवरफ़्लो होता है (उदाहरण)
  • लिंक की गई सूची को मिटाने पर, लूप इंडेक्स कम हो जाता है (उदाहरण)
  • असल मैक्स वैल्यू बताने के बजाय, -1 को बिना साइन वाला टाइप असाइन करना (उदाहरण)
  • ऐसे लूप जो शर्त में बिना हस्ताक्षर वाले पूर्णांक को घटाते हैं (उदाहरण, उदाहरण)

हमारा सुझाव है कि डेवलपर यह पक्का कर लें कि सैनिटाइज़र के किसी डेटा के ओवरफ़्लो का पता चलने पर, वह डेटा असल में नुकसान पहुंचाने वाला न हो. साथ ही, उससे सुरक्षा पर कोई असर न पड़ रहा हो. इसके बाद ही, डेटा को सैनिटाइज़ करने की सुविधा बंद करें.

IntSan बंद करना

ब्लॉकलिस्ट या फ़ंक्शन एट्रिब्यूट की मदद से, IntSan को बंद किया जा सकता है. इसे कम ही इस्तेमाल करें और सिर्फ़ तब इस्तेमाल करें, जब कोड को फिर से लिखना सही न हो या परफ़ॉर्मेंस में समस्या हो.

फ़ंक्शन एट्रिब्यूट और ब्लॉकलिस्ट फ़ाइल के फ़ॉर्मैट की मदद से, IntSan को बंद करने के बारे में ज़्यादा जानने के लिए, अपस्ट्रीम Clang दस्तावेज़ देखें. टारगेट किए गए सैनिटाइज़र की जानकारी देने वाले सेक्शन के नाम का इस्तेमाल करके, किसी खास सैनिटाइज़र के लिए ब्लॉकलिस्ट का दायरा तय किया जाना चाहिए. इससे, अन्य सैनिटाइज़र पर असर नहीं पड़ेगा.

पुष्टि करें

फ़िलहाल, खास तौर पर इंटिजर ओवरफ़्लो सैनिटाइज़ेशन के लिए, सीटीएस का कोई टेस्ट नहीं है. इसके बजाय, पक्का करें कि IntSan चालू होने पर और बंद होने पर, दोनों ही स्थितियों में सीटीएस टेस्ट पास हो जाएं. इससे यह पुष्टि की जा सकेगी कि इसका डिवाइस पर कोई असर नहीं पड़ रहा है.

सीमाओं को सैनिटाइज़ करना

BoundsSanitizer (BoundSan), ऐरे ऐक्सेस के आस-पास सीमाओं की जांच करने के लिए, बाइनरी में इंस्ट्रूमेंटेशन जोड़ता है. ये जांच तब जोड़ी जाती हैं, जब कंपाइलर, कंपाइल करने के समय यह साबित नहीं कर पाता कि ऐक्सेस सुरक्षित होगा. साथ ही, अगर ऐरे का साइज़ रनटाइम के दौरान पता चलता है, तो इसकी जांच की जा सकती है. Android 10, ब्लूटूथ और कोडेक में BoundSan को डिप्लॉय करता है. BoundSan, कंपाइलर की ओर से उपलब्ध कराया जाता है. साथ ही, यह पूरे प्लैटफ़ॉर्म के अलग-अलग कॉम्पोनेंट में डिफ़ॉल्ट रूप से चालू होता है.

लागू करना

BoundSan, UBSan के सीमाओं को सुरक्षित रखने वाले टूल का इस्तेमाल करता है. यह समस्या हल करने की सुविधा, हर मॉड्यूल के लेवल पर चालू होती है. इससे Android के अहम कॉम्पोनेंट को सुरक्षित रखने में मदद मिलती है. इसलिए, इसे बंद नहीं किया जाना चाहिए.

हमारा सुझाव है कि आप अन्य कॉम्पोनेंट के लिए BoundSan को चालू करें. इसके लिए, ऐसे नेटिव कोड का इस्तेमाल करना चाहिए जिनमें विशेष अनुमतियां हों या जो बहुत जटिल हों. साथ ही, ऐसे कोड का इस्तेमाल करना चाहिए जो उपयोगकर्ता के अविश्वसनीय इनपुट को पार्स करता हो. BoundSan को चालू करने से जुड़ी परफ़ॉर्मेंस में होने वाली बढ़ोतरी, उन ऐरे ऐक्सेस की संख्या पर निर्भर करती है जिन्हें सुरक्षित नहीं माना जा सकता. औसतन, थोड़ा ओवरहेड प्रतिशत होने की उम्मीद करें और देखें कि परफ़ॉर्मेंस पर असर पड़ रहा है या नहीं.

ब्लूप्रिंट फ़ाइलों में BoundSan की सुविधा चालू करना

BoundSan को ब्लूप्रिंट फ़ाइलों में चालू किया जा सकता है. इसके लिए, बाइनरी और लाइब्रेरी मॉड्यूल के लिए, misc_undefined sanitize प्रॉपर्टी में "bounds" जोड़ें:

    sanitize: {
       misc_undefined: ["bounds"],
       diag: {
          misc_undefined: ["bounds"],
       },
       BLOCKLIST: "modulename_BLOCKLIST.txt",
diag

diag प्रॉपर्टी, सैनिटाइज़र के लिए गड़बड़ी का पता लगाने वाले मोड को चालू करती है. गड़बड़ी की जानकारी देने वाले मोड का इस्तेमाल सिर्फ़ टेस्टिंग के दौरान करें. डाइग्नोस्टिक्स मोड, ओवरफ़्लो होने पर प्रोसेस को बंद नहीं करता. इससे, सुरक्षा से जुड़े फ़ायदे काफ़ी हद तक कम हो जाते हैं और परफ़ॉर्मेंस पर ज़्यादा असर पड़ता है. इसलिए, इसका सुझाव प्रोडक्शन बिल्ड के लिए नहीं दिया जाता.

ब्लॉकलिस्ट

BLOCKLIST प्रॉपर्टी की मदद से, BLOCKLIST फ़ाइल तय की जा सकती है. डेवलपर इसका इस्तेमाल करके, फ़ंक्शन और सोर्स फ़ाइलों को साफ़ किए जाने से रोक सकते हैं. इस प्रॉपर्टी का इस्तेमाल सिर्फ़ तब करें, जब परफ़ॉर्मेंस में कोई समस्या हो और टारगेट की गई फ़ाइलों/फ़ंक्शन का योगदान काफ़ी ज़्यादा हो. इन फ़ाइलों/फ़ंक्शन का मैन्युअल तौर पर ऑडिट करें, ताकि यह पक्का किया जा सके कि ऐरे के ऐक्सेस सुरक्षित हैं. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.

मेकफ़ाइलों में BoundSan चालू करना

बाइनरी और लाइब्रेरी मॉड्यूल के लिए, LOCAL_SANITIZE वैरिएबल में "bounds" जोड़कर, मेकफ़ाइल में BoundSan को चालू किया जा सकता है:

    LOCAL_SANITIZE := bounds
    # Optional features
    LOCAL_SANITIZE_DIAG := bounds
    LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt

LOCAL_SANITIZE, कॉमा लगाकर अलग की गई sanitizers की सूची को स्वीकार करता है.

LOCAL_SANITIZE_DIAG, गड़बड़ी की जानकारी देने वाला मोड चालू करता है. गड़बड़ी की जानकारी देने वाले मोड का इस्तेमाल सिर्फ़ टेस्टिंग के दौरान करें. डाइग्नोस्टिक्स मोड, ओवरफ़्लो होने पर प्रोसेस को बंद नहीं करता. इससे, प्रोसेस को कम करने के सुरक्षा फ़ायदे काफ़ी हद तक कम हो जाते हैं. साथ ही, परफ़ॉर्मेंस पर ज़्यादा असर पड़ता है. इसलिए, प्रोडक्शन बिल्ड के लिए इसका सुझाव नहीं दिया जाता.

LOCAL_SANITIZE_BLOCKLIST की मदद से, BLOCKLIST वाली फ़ाइल तय की जा सकती है. इससे डेवलपर, फ़ंक्शन और सोर्स फ़ाइलों को साफ़ किए जाने से रोक सकते हैं. इस प्रॉपर्टी का इस्तेमाल सिर्फ़ तब करें, जब परफ़ॉर्मेंस में कोई समस्या हो और टारगेट की गई फ़ाइलों/फ़ंक्शन का योगदान काफ़ी ज़्यादा हो. इन फ़ाइलों/फ़ंक्शन का मैन्युअल तौर पर ऑडिट करें, ताकि यह पक्का किया जा सके कि ऐरे के ऐक्सेस सुरक्षित हैं. ज़्यादा जानकारी के लिए, समस्या हल करना देखें.

BoundSan बंद करना

फ़ंक्शन और सोर्स फ़ाइलों में, ब्लॉकलिस्ट या फ़ंक्शन एट्रिब्यूट की मदद से BoundSan को बंद किया जा सकता है. BoundSan को चालू रखना सबसे अच्छा होता है. इसलिए, इसे सिर्फ़ तब बंद करें, जब फ़ंक्शन या फ़ाइल की परफ़ॉर्मेंस पर ज़्यादा असर पड़ रहा हो और सोर्स की मैन्युअल तौर पर समीक्षा की जा चुकी हो.

फ़ंक्शन एट्रिब्यूट और ब्लॉकलिस्ट फ़ाइल फ़ॉर्मैटिंग की मदद से, BoundSan को बंद करने के बारे में ज़्यादा जानने के लिए, Clang LLVM का दस्तावेज़ देखें. टारगेट किए गए सैनिटाइज़र के सेक्शन के नाम का इस्तेमाल करके, किसी खास सैनिटाइज़र को ब्लॉकलिस्ट में शामिल करें. इससे, अन्य सैनिटाइज़र पर असर नहीं पड़ेगा.

पुष्टि करें

BoundSan के लिए, सीटीएस टेस्ट उपलब्ध नहीं हैं. इसके बजाय, पक्का करें कि BoundSan चालू होने पर और बंद होने पर, दोनों ही स्थितियों में सीटीएस टेस्ट पास हो जाएं. इससे यह पुष्टि की जा सकेगी कि BoundSan का डिवाइस पर कोई असर नहीं पड़ रहा है.

समस्या का हल

BoundSan चालू करने के बाद, कॉम्पोनेंट की पूरी तरह से जांच करें. इससे यह पक्का किया जा सकेगा कि पहले से मौजूद, सीमाओं से बाहर के ऐक्सेस को ठीक कर दिया गया है.

BoundSan की गड़बड़ियों की पहचान आसानी से की जा सकती है, क्योंकि इनमें यह मैसेज शामिल होता है:

    pid: ###, tid: ###, name: Binder:###  >>> /system/bin/foobar <<<
    signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    Abort message: 'ubsan: out-of-bounds'

गड़बड़ी की जानकारी देने वाले मोड में चलने पर, सोर्स फ़ाइल, लाइन नंबर, और इंडेक्स वैल्यू को logcat में प्रिंट किया जाता है. डिफ़ॉल्ट रूप से, यह मोड 'कार्रवाई रोकें' मैसेज नहीं दिखाता. किसी भी तरह की गड़बड़ी की जांच करने के लिए, logcat देखें.

    external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'