UndefinedBehaviorSanitizer

UnknownBehaviorSanitizer (UBSan) ดำเนินการใช้เครื่องมือเวลาคอมไพล์เพื่อตรวจสอบพฤติกรรมที่ไม่ได้กำหนดประเภทต่างๆ แม้ว่า UBSan จะสามารถตรวจจับ ข้อบกพร่องด้านพฤติกรรมที่ไม่ได้กำหนดได้มากมาย แต่ Android ก็รองรับ:

  • การจัดตำแหน่ง
  • บูล
  • ขอบเขต
  • แจกแจง
  • ลอยหล่อล้น
  • ลอยหารด้วยศูนย์
  • จำนวนเต็มหารด้วยศูนย์
  • แอตทริบิวต์ที่ไม่เป็นโมฆะ
  • โมฆะ
  • กลับ
  • ส่งคืนแอตทริบิวต์ nonnull
  • กะฐาน
  • กะเลขชี้กำลัง
  • ลงนามจำนวนเต็มล้น
  • ไม่สามารถเข้าถึงได้
  • จำนวนเต็มล้นที่ไม่ได้ลงนาม
  • vla-ผูกไว้

unsigned-integer-overflow แม้จะไม่ใช่ลักษณะการทำงานที่ไม่ได้กำหนดในทางเทคนิค แต่ก็รวมอยู่ในโปรแกรมฆ่าเชื้อและใช้ในโมดูล Android จำนวนมาก รวมถึงส่วนประกอบของเซิร์ฟเวอร์สื่อ เพื่อกำจัดช่องโหว่ที่แฝงอยู่ของจำนวนเต็มล้น

การนำไปปฏิบัติ

ในระบบบิลด์ Android คุณสามารถเปิดใช้งาน UBSan ทั่วโลกหรือภายในเครื่องได้ หากต้องการเปิดใช้งาน UBSan ทั่วโลก ให้ตั้งค่า SANITIZE_TARGET ใน Android.mk หากต้องการเปิดใช้งาน 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 เท่านั้น

รายงานข้อผิดพลาดได้ดีขึ้น

การใช้งาน UBSan เริ่มต้นของ Android จะเรียกใช้ฟังก์ชันที่ระบุเมื่อพบพฤติกรรมที่ไม่ได้กำหนด ตามค่าเริ่มต้น ฟังก์ชันนี้จะถูกยกเลิก อย่างไรก็ตาม ตั้งแต่เดือนตุลาคม 2559 เป็นต้นไป UBSan บน Android จะมีไลบรารีรันไทม์เสริมที่ให้การรายงานข้อผิดพลาดโดยละเอียดมากขึ้น รวมถึงประเภทของพฤติกรรมที่ไม่ได้กำหนดที่พบ ข้อมูลไฟล์และบรรทัดซอร์สโค้ด หากต้องการเปิดใช้งานการรายงานข้อผิดพลาดนี้ด้วยการตรวจสอบจำนวนเต็ม ให้เพิ่มสิ่งต่อไปนี้ในไฟล์ 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')

การฆ่าเชื้อล้นจำนวนเต็ม

จำนวนเต็มล้นโดยไม่ได้ตั้งใจอาจทำให้เกิดความเสียหายของหน่วยความจำหรือช่องโหว่ในการเปิดเผยข้อมูลในตัวแปรที่เกี่ยวข้องกับการเข้าถึงหน่วยความจำหรือการจัดสรรหน่วยความจำ เพื่อต่อสู้กับสิ่งนี้ เราได้เพิ่ม UndefineBehaviorSanitizer (UBSan) ของ Clang ที่ลงชื่อและไม่ได้ลงนาม โปรแกรมฆ่าเชื้อล้นจำนวนเต็ม เพื่อ ทำให้เฟรมเวิร์กสื่อใน Android 7.0 แข็งแกร่งขึ้น ใน Android 9 เรา ได้ขยาย UBsan เพื่อให้ครอบคลุมส่วนประกอบต่างๆ มากขึ้น และปรับปรุงการรองรับระบบบิลด์ของมัน

สิ่งนี้ได้รับการออกแบบมาเพื่อเพิ่มการตรวจสอบการดำเนินการ/คำสั่งทางคณิตศาสตร์ ซึ่งอาจล้นออกมา เพื่อยกเลิกกระบวนการอย่างปลอดภัยหากเกิดการโอเวอร์โฟลว์ สารฆ่าเชื้อเหล่านี้สามารถบรรเทาความเสียหายของหน่วยความจำทั้งคลาสและช่องโหว่ในการเปิดเผยข้อมูลที่ต้นตอของสาเหตุคือจำนวนเต็มล้น เช่น ช่องโหว่ Stagefright ดั้งเดิม

ตัวอย่างและที่มา

คอมไพเลอร์จัดเตรียม Integer Overflow Sanitization (IntSan) และเพิ่มเครื่องมือลงในไบนารีในช่วงเวลาคอมไพล์เพื่อตรวจจับการโอเวอร์โฟลว์ทางคณิตศาสตร์ โดยจะเปิดใช้งานตามค่าเริ่มต้นในส่วนประกอบต่างๆ ทั่วทั้งแพลตฟอร์ม เช่น /platform/external/libnl/Android.bp

การนำไปปฏิบัติ

IntSan ใช้น้ำยาฆ่าเชื้อล้นจำนวนเต็มที่ลงนามและไม่ได้ลงนามของ UBSan การบรรเทาผลกระทบนี้เปิดใช้งานในระดับต่อโมดูล ช่วยรักษาส่วนประกอบที่สำคัญของ Android ให้ปลอดภัยและไม่ควรปิดใช้งาน

เราขอแนะนำให้คุณเปิดใช้งานการฆ่าเชื้อจำนวนเต็มล้นสำหรับส่วนประกอบเพิ่มเติม ตัวเลือกที่เหมาะสมคือโค้ดเนทีฟที่มีสิทธิพิเศษหรือโค้ดเนทีฟที่จะแยกวิเคราะห์อินพุตของผู้ใช้ที่ไม่น่าเชื่อถือ มีค่าใช้จ่ายด้านประสิทธิภาพเล็กน้อยที่เกี่ยวข้องกับน้ำยาฆ่าเชื้อ ซึ่งขึ้นอยู่กับการใช้โค้ดและความแพร่หลายของการดำเนินการทางคณิตศาสตร์ คาดว่าจะมีเปอร์เซ็นต์ค่าใช้จ่ายเล็กน้อยและทดสอบว่าประสิทธิภาพเป็นปัญหาหรือไม่

รองรับ IntSan ใน makefiles

หากต้องการเปิดใช้งาน IntSan ใน makefile ให้เพิ่ม:

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",
       },

เช่นเดียวกับไฟล์ make คุณสมบัติ integer_overflow เป็นชุดตัวเลือกที่จัดทำแพ็กเกจไว้ล่วงหน้าสำหรับตัวฆ่าเชื้อล้นจำนวนเต็มทั้งแบบลงนามและไม่ได้ลงนามพร้อมด้วย BLOCKLIST ดีฟอลต์

ชุดคุณสมบัติ diag เปิดใช้งานโหมดการวินิจฉัยสำหรับน้ำยาฆ่าเชื้อ ใช้โหมดการวินิจฉัยระหว่างการทดสอบเท่านั้น โหมดการวินิจฉัยจะไม่ยกเลิกเมื่อมีการโอเวอร์โฟลว์ ซึ่งจะลบล้างข้อดีด้านความปลอดภัยของการบรรเทาผลกระทบในรุ่นผู้ใช้โดยสิ้นเชิง ดู การแก้ไขปัญหา สำหรับรายละเอียดเพิ่มเติม

คุณสมบัติ BLOCKLIST อนุญาตให้ระบุข้อกำหนดของไฟล์ 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')

เมื่อพบการดำเนินการทางคณิตศาสตร์ที่เป็นปัญหาแล้ว ตรวจสอบให้แน่ใจว่าโอเวอร์โฟลว์นั้นไม่เป็นพิษเป็นภัยและมีเจตนา (เช่น ไม่มีผลกระทบด้านความปลอดภัย) คุณสามารถแก้ไขปัญหาการยกเลิกเจลทำความสะอาดได้โดย:

  • การปรับโครงสร้างโค้ดใหม่เพื่อหลีกเลี่ยงการโอเวอร์โฟลว์ ( ตัวอย่าง )
  • ล้นอย่างชัดเจนผ่านฟังก์ชัน __builtin__*_overflow ของ Clang ( ตัวอย่าง )
  • ปิดการใช้งานการฆ่าเชื้อในฟังก์ชันโดยการระบุแอตทริบิวต์ no_sanitize ( ตัวอย่าง )
  • การปิดใช้งานการฆ่าเชื้อฟังก์ชันหรือไฟล์ต้นฉบับผ่านไฟล์ BLOCKLIST ( ตัวอย่าง )

คุณควรใช้วิธีแก้ปัญหาที่ละเอียดที่สุดเท่าที่จะเป็นไปได้ ตัวอย่างเช่น ฟังก์ชันขนาดใหญ่ที่มีการดำเนินการทางคณิตศาสตร์จำนวนมากและการดำเนินการโอเวอร์โฟลว์ครั้งเดียวควรมีการปรับโครงสร้างการดำเนินการเดียว แทนที่จะเป็นฟังก์ชัน BLOCKLISTed ทั้งหมด

รูปแบบทั่วไปที่อาจส่งผลให้เกิดการล้นที่ไม่เป็นอันตราย ได้แก่:

  • Casts โดยนัย ซึ่งมีการโอเวอร์โฟลว์ที่ไม่ได้ลงนามเกิดขึ้นก่อนที่จะถูกส่งไปยังประเภทที่ลงนาม ( ตัวอย่าง )
  • การลบรายการที่เชื่อมโยงซึ่งจะลดดัชนีลูปเมื่อลบ ( ตัวอย่าง )
  • การกำหนดประเภทที่ไม่ได้ลงนามให้กับ -1 แทนที่จะระบุค่าสูงสุดตามจริง ( ตัวอย่าง )
  • วนซ้ำซึ่งลดจำนวนเต็มที่ไม่ได้ลงนามในเงื่อนไข ( ตัวอย่าง ตัวอย่าง )

ขอแนะนำให้นักพัฒนารับรองว่ากรณีที่น้ำยาฆ่าเชื้อตรวจพบการไหลล้นว่าไม่เป็นพิษเป็นภัยโดยไม่มีผลข้างเคียงหรือผลกระทบด้านความปลอดภัยโดยไม่ได้ตั้งใจ ก่อนที่จะปิดใช้งานการฆ่าเชื้อ

ปิดการใช้งาน IntSan

คุณสามารถปิดการใช้งาน IntSan ด้วย BLOCKLIST หรือคุณลักษณะของฟังก์ชัน ปิดใช้งานเท่าที่จำเป็นและเฉพาะเมื่อการปรับโครงสร้างโค้ดใหม่นั้นไม่สมเหตุสมผล หรือหากมีค่าใช้จ่ายด้านประสิทธิภาพที่เป็นปัญหา

ดูเอกสารประกอบ upstream Clang สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการปิดใช้งาน IntSan ด้วย คุณลักษณะฟังก์ชัน และ การจัดรูปแบบไฟล์ BLOCKLIST รายชื่อบล็อกควรกำหนดขอบเขตไว้ที่น้ำยาฆ่าเชื้อโดยเฉพาะโดยใช้ชื่อส่วนที่ระบุน้ำยาฆ่าเชื้อเป้าหมาย เพื่อหลีกเลี่ยงไม่ให้ส่งผลกระทบต่อน้ำยาฆ่าเชื้ออื่นๆ

การตรวจสอบ

ในปัจจุบัน ยังไม่มีการทดสอบ CTS สำหรับการฆ่าเชื้อจำนวนเต็มล้นโดยเฉพาะ โปรดตรวจสอบให้แน่ใจว่าการทดสอบ CTS ผ่านหรือไม่เปิดใช้งาน IntSan เพื่อตรวจสอบว่าไม่มีผลกระทบต่ออุปกรณ์

การฆ่าเชื้อแบบมีขอบเขต

BoundsSanitizer (BoundSan) เพิ่มเครื่องมือวัดให้กับไบนารีเพื่อแทรกการตรวจสอบขอบเขตรอบการเข้าถึงอาร์เรย์ การตรวจสอบเหล่านี้จะถูกเพิ่มหากคอมไพลเลอร์ไม่สามารถพิสูจน์ได้ในขณะคอมไพล์ว่าการเข้าถึงจะปลอดภัย และจะทราบขนาดของอาเรย์ขณะรันไทม์หรือไม่ เพื่อให้สามารถตรวจสอบได้ Android 10 ปรับใช้ BoundSan ใน Bluetooth และตัวแปลงสัญญาณ BoundSan จัดทำโดยคอมไพเลอร์และเปิดใช้งานตามค่าเริ่มต้นในส่วนประกอบต่างๆ ทั่วทั้งแพลตฟอร์ม

การนำไปปฏิบัติ

BoundSan ใช้น้ำยาฆ่าเชื้อ BoundSan ของ UBSan การบรรเทาผลกระทบนี้เปิดใช้งานในระดับต่อโมดูล ช่วยรักษาองค์ประกอบสำคัญของ Android ให้ปลอดภัยและไม่ควรปิดใช้งาน

เราขอแนะนำให้คุณเปิดใช้งาน BoundSan สำหรับส่วนประกอบเพิ่มเติม ตัวเลือกที่เหมาะสมคือโค้ดเนทีฟที่มีสิทธิพิเศษหรือโค้ดเนทีฟที่ซับซ้อนซึ่งจะแยกวิเคราะห์อินพุตของผู้ใช้ที่ไม่น่าเชื่อถือ ค่าใช้จ่ายด้านประสิทธิภาพที่เกี่ยวข้องกับการเปิดใช้งาน BoundSan ขึ้นอยู่กับจำนวนการเข้าถึงอาร์เรย์ที่ไม่สามารถพิสูจน์ได้ว่าปลอดภัย คาดว่าจะมีเปอร์เซ็นต์ค่าใช้จ่ายโดยเฉลี่ยเล็กน้อย และทดสอบว่าประสิทธิภาพเป็นปัญหาหรือไม่

การเปิดใช้งาน BoundSan ในไฟล์พิมพ์เขียว

สามารถเปิดใช้งาน BoundSan ในไฟล์พิมพ์เขียวได้โดยเพิ่ม "bounds" ให้กับคุณสมบัติการฆ่าเชื้อ misc_undefined สำหรับโมดูลไบนารีและไลบรารี:

    sanitize: {
       misc_undefined: ["bounds"],
       diag: {
          misc_undefined: ["bounds"],
       },
       BLOCKLIST: "modulename_BLOCKLIST.txt",
วินิจฉัย

คุณสมบัติ diag เปิดใช้งานโหมดการวินิจฉัยสำหรับน้ำยาฆ่าเชื้อ ใช้โหมดการวินิจฉัยระหว่างการทดสอบเท่านั้น โหมดการวินิจฉัยไม่ยกเลิกเมื่อโอเวอร์โฟลว์ ซึ่งจะลบล้างข้อได้เปรียบด้านความปลอดภัยของการบรรเทาผลกระทบ และมีค่าใช้จ่ายด้านประสิทธิภาพที่สูงกว่า ดังนั้นจึงไม่แนะนำสำหรับรุ่นที่ใช้งานจริง

รายการบล็อก

คุณสมบัติ BLOCKLIST อนุญาตให้ระบุข้อกำหนดของไฟล์ BLOCKLIST ที่นักพัฒนาสามารถใช้เพื่อป้องกันไม่ให้ฟังก์ชันและไฟล์ต้นฉบับถูกฆ่าเชื้อ ใช้คุณสมบัตินี้เฉพาะในกรณีที่ประสิทธิภาพเป็นปัญหาและไฟล์/ฟังก์ชันเป้าหมายมีส่วนอย่างมาก ตรวจสอบไฟล์/ฟังก์ชันเหล่านี้ด้วยตนเองเพื่อให้แน่ใจว่าการเข้าถึงอาร์เรย์มีความปลอดภัย ดู การแก้ไขปัญหา สำหรับรายละเอียดเพิ่มเติม

การเปิดใช้งาน BoundSan ใน makefiles

BoundSan สามารถเปิดใช้งานใน makefiles ได้โดยเพิ่ม "bounds" ให้กับตัวแปร LOCAL_SANITIZE สำหรับโมดูลไบนารีและไลบรารี:

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

LOCAL_SANITIZE ยอมรับรายการน้ำยาฆ่าเชื้อโดยคั่นด้วยเครื่องหมายจุลภาค

LOCAL_SANITIZE_DIAG เปิดโหมดการวินิจฉัย ใช้โหมดการวินิจฉัยระหว่างการทดสอบเท่านั้น โหมดการวินิจฉัยไม่ยกเลิกเมื่อโอเวอร์โฟลว์ ซึ่งจะลบล้างข้อได้เปรียบด้านความปลอดภัยของการบรรเทาผลกระทบ และมีค่าใช้จ่ายด้านประสิทธิภาพที่สูงกว่า ดังนั้นจึงไม่แนะนำสำหรับรุ่นที่ใช้งานจริง

LOCAL_SANITIZE_BLOCKLIST อนุญาตข้อกำหนดของไฟล์ BLOCKLIST ที่ช่วยให้นักพัฒนาสามารถป้องกันไม่ให้ฟังก์ชันและไฟล์ต้นฉบับถูกฆ่าเชื้อ ใช้คุณสมบัตินี้เฉพาะในกรณีที่ประสิทธิภาพเป็นปัญหาและไฟล์/ฟังก์ชันเป้าหมายมีส่วนอย่างมาก ตรวจสอบไฟล์/ฟังก์ชันเหล่านี้ด้วยตนเองเพื่อให้แน่ใจว่าการเข้าถึงอาร์เรย์มีความปลอดภัย ดู การแก้ไขปัญหา สำหรับรายละเอียดเพิ่มเติม

ปิดการใช้งาน BoundSan

คุณสามารถปิดการใช้งาน BoundSan ในฟังก์ชั่นและไฟล์ต้นฉบับด้วย BLOCKLIST หรือคุณสมบัติของฟังก์ชั่น ทางที่ดีควรเปิดใช้งาน BoundSan ไว้ ดังนั้นให้ปิดใช้งานเฉพาะในกรณีที่ฟังก์ชันหรือไฟล์สร้างโอเวอร์เฮดด้านประสิทธิภาพจำนวนมาก และแหล่งที่มาได้รับการตรวจสอบด้วยตนเองแล้วเท่านั้น

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการปิดใช้งาน BoundSan ด้วย คุณลักษณะของฟังก์ชัน และ การจัดรูปแบบไฟล์ BLOCKLIST โปรดดู เอกสารประกอบของ Clang LLVM กำหนดขอบเขตรายการบล็อกให้ครอบคลุมถึงน้ำยาฆ่าเชื้อโดยเฉพาะโดยใช้ชื่อส่วนที่ระบุน้ำยาฆ่าเชื้อเป้าหมาย เพื่อหลีกเลี่ยงไม่ให้ส่งผลกระทบต่อน้ำยาฆ่าเชื้ออื่นๆ

การตรวจสอบ

ไม่มีการทดสอบ CTS สำหรับ BoundSan โดยเฉพาะ โปรดตรวจสอบให้แน่ใจว่าการทดสอบ CTS ผ่านหรือไม่เปิดใช้งาน BoundSan เพื่อตรวจสอบว่าไม่มีผลกระทบต่ออุปกรณ์

การแก้ไขปัญหา

ทดสอบส่วนประกอบอย่างละเอียดหลังจากเปิดใช้งาน BoundSan เพื่อให้แน่ใจว่าการเข้าถึงนอกขอบเขตที่ตรวจไม่พบก่อนหน้านี้ได้รับการแก้ไข

ข้อผิดพลาด BoundSan สามารถระบุได้อย่างง่ายดายเนื่องจากมีข้อความยกเลิก tombstone ต่อไปนี้:

    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]'