AddressSanitizer ที่ทำงานด้วยความช่วยเหลือของฮาร์ดแวร์

ดูข้อมูลเกี่ยวกับวิธีอ่านรายงานการหยุดทำงานของ HWASan ได้ที่ ทำความเข้าใจรายงาน HWASan

Hardware-assisted AddressSanitizer (HWASan) เป็นเครื่องมือตรวจหาข้อผิดพลาดของหน่วยความจำที่คล้ายกับ AddressSanitizer HWASan ใช้ RAM น้อยกว่า ASan มาก ซึ่งเหมาะสำหรับการ ล้างข้อมูลทั้งระบบ HWASan พร้อมใช้งานใน Android 10 ขึ้นไปและในฮาร์ดแวร์ AArch64 เท่านั้น

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

เมื่อเทียบกับ ASan แบบคลาสสิก HWASan มีลักษณะดังนี้

  • ค่าใช้จ่าย CPU ที่คล้ายกัน (~2 เท่า)
  • ค่าใช้จ่ายขนาดโค้ดที่คล้ายกัน (40–50%)
  • ค่าใช้จ่าย RAM ที่น้อยกว่ามาก (10–35%)

HWASan ตรวจพบชุดข้อบกพร่องชุดเดียวกับ ASan ดังนี้

  • บัฟเฟอร์สแต็กและฮีปโอเวอร์โฟลว์/อันเดอร์โฟลว์
  • การใช้ฮีปหลังจากปล่อย
  • การใช้สแต็กนอกขอบเขต
  • การปล่อยซ้ำ/การปล่อยแบบไม่ระบุ

นอกจากนี้ HWASan ยังตรวจพบการใช้สแต็กหลังจากส่งคืน

HWASan (เช่นเดียวกับ ASan) เข้ากันได้กับ UBSan, โดยสามารถเปิดใช้ทั้ง 2 อย่างในเป้าหมายได้พร้อมกัน

รายละเอียดและข้อจำกัดในการใช้งาน

HWASan อิงตามแนวทางการติดแท็กหน่วยความจำ ซึ่งจะมีการเชื่อมโยงค่าแท็กแบบสุ่มขนาดเล็กกับทั้งพอยน์เตอร์และช่วงที่อยู่หน่วยความจำ การเข้าถึงหน่วยความจำ จะถูกต้องก็ต่อเมื่อพอยน์เตอร์และแท็กหน่วยความจำตรงกัน HWASan อาศัยฟีเจอร์ Top Byte Ignore (TBI) ของ ARMv8 ซึ่งเรียกอีกอย่างว่า การติดแท็กที่อยู่เสมือน เพื่อจัดเก็บแท็กพอยน์เตอร์ใน บิตสูงสุดของที่อยู่

อ่านเพิ่มเติมเกี่ยวกับ การออกแบบ ของ HWASan ได้ในเว็บไซต์เอกสารประกอบของ Clang

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

อย่างไรก็ตาม HWASan มีค่าแท็กที่เป็นไปได้จำนวนจำกัด (256) ซึ่งหมายความว่ามีโอกาส 0.4% ที่จะพลาดข้อบกพร่องใดๆ ในระหว่างการดำเนินการโปรแกรม 1 ครั้ง

ข้อกำหนด

เคอร์เนล Android ทั่วไปเวอร์ชันล่าสุด (4.14 ขึ้นไป) รองรับ HWASan ทันที สาขาเฉพาะของ Android 10 ไม่รองรับ HWASan

การรองรับ Userspace สำหรับ HWASan พร้อมให้บริการตั้งแต่ Android 11 เป็นต้นไป

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

หากคุณสร้างด้วย Toolchain ที่กำหนดเอง โปรดตรวจสอบว่า Toolchain นั้นมีทุกอย่างจนถึง LLVM Commit c336557f

ใช้ HWASan

ใช้คำสั่งต่อไปนี้เพื่อสร้างแพลตฟอร์มทั้งหมดโดยใช้ HWASan

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

คุณสามารถเพิ่มการตั้งค่า SANITIZE_TARGET ลงในการกำหนดผลิตภัณฑ์ได้ เช่นเดียวกับ aosp_coral_hwasan เพื่อความสะดวก

สำหรับผู้ใช้ที่คุ้นเคยกับ AddressSanitizer ความซับซ้อนในการบิลด์ส่วนใหญ่จะหายไป

  • ไม่จำเป็นต้องเรียกใช้ make 2 ครั้ง
  • การสร้างแบบเพิ่มทีละส่วนใช้งานได้ทันที
  • ไม่จำเป็นต้องแฟลชข้อมูลผู้ใช้

ข้อจำกัดบางอย่างของ AddressSanitizer ก็หายไปด้วย

  • รองรับไฟล์ปฏิบัติการแบบคงที่
  • ข้ามการล้างข้อมูลเป้าหมายอื่นที่ไม่ใช่ libc ได้ ไม่เหมือนกับ ASan ที่ ไม่จำเป็นต้องล้างข้อมูลไลบรารีหากไฟล์ปฏิบัติการที่ลิงก์กับไลบรารีนั้นต้องล้างข้อมูลด้วย

คุณสามารถสลับระหว่าง HWASan กับอิมเมจปกติได้อย่างอิสระที่หมายเลขบิลด์เดียวกัน (หรือสูงกว่า) ได้ ไม่จำเป็นต้องล้างข้อมูลอุปกรณ์

หากต้องการข้ามการล้างข้อมูลโมดูล ให้ใช้ LOCAL_NOSANITIZE := hwaddress (Android.mk) หรือ sanitize: { hwaddress: false } (Android.bp)

ล้างข้อมูลเป้าหมายแต่ละรายการ

คุณเปิดใช้ HWASan ต่อเป้าหมายได้ในการสร้างปกติ (ที่ไม่ได้ล้างข้อมูล) ตราบใดที่ libc.so ได้รับการล้างข้อมูลด้วย เพิ่ม hwaddress: true ลงในบล็อกการล้างข้อมูลใน "libc_defaults" ใน bionic/libc/Android.bp จากนั้นทำแบบเดียวกันในเป้าหมายที่คุณกำลังใช้งาน

โปรดทราบว่าการล้างข้อมูล libc จะเปิดใช้การติดแท็กการจัดสรรหน่วยความจำฮีปทั้งระบบ รวมถึงการ ตรวจสอบแท็กสำหรับการดำเนินการหน่วยความจำภายใน libc.so ซึ่งอาจตรวจพบข้อบกพร่องแม้ในไบนารี ที่ไม่ได้เปิดใช้ HWASan หากการเข้าถึงหน่วยความจำที่ไม่ถูกต้องอยู่ใน libc.so (เช่น pthread_mutex_unlock() ใน Mutex ที่ delete())

คุณไม่จำเป็นต้องเปลี่ยนไฟล์บิลด์ใดๆ หากสร้างแพลตฟอร์มทั้งหมดโดยใช้ HWASan

สแต็กเทรซที่ดีขึ้น

HWASan ใช้ Unwinder ที่รวดเร็วซึ่งอิงตามพอยน์เตอร์เฟรมเพื่อบันทึกสแต็ก เทรซสำหรับเหตุการณ์การจัดสรรและการยกเลิกการจัดสรรหน่วยความจำทุกรายการใน โปรแกรม Android เปิดใช้พอยน์เตอร์เฟรมในโค้ด AArch64 โดยค่าเริ่มต้น ดังนั้นจึงใช้งานได้ดีในทางปฏิบัติ หากต้องการยกเลิกการจัดสรรผ่าน โค้ดที่มีการจัดการ ให้ตั้งค่า HWASAN_OPTIONS=fast_unwind_on_malloc=0 ในสภาพแวดล้อมของกระบวนการ โปรดทราบว่าสแต็กเทรซการเข้าถึงหน่วยความจำที่ไม่ถูกต้องจะใช้ Unwinder "ช้า" โดยค่าเริ่มต้น การตั้งค่านี้จะส่งผลต่อการติดตามการจัดสรรและการยกเลิกการจัดสรรเท่านั้น ตัวเลือกนี้อาจใช้ CPU มาก ขึ้นอยู่กับโหลด

การแปลงเป็นสัญลักษณ์

ดูการแปลงเป็นสัญลักษณ์ ใน "ทำความเข้าใจรายงาน HWASan"

HWASan ในแอป

HWASan ไม่สามารถดูโค้ด Java ได้ แต่ ตรวจพบข้อบกพร่องในไลบรารี JNI ได้ ซึ่งคล้ายกับ AddressSanitizer จนถึง Android 14 ระบบไม่ รองรับการเรียกใช้แอป HWASan ในอุปกรณ์ที่ไม่ใช่ HWASan

ในอุปกรณ์ HWASan คุณสามารถตรวจสอบแอปด้วย HWASan ได้โดยสร้าง โค้ดของแอปด้วย SANITIZE_TARGET:=hwaddress ใน Make หรือ -fsanitize=hwaddress ในแฟล็กคอมไพเลอร์ ในอุปกรณ์ที่ไม่ใช่ HWASan (ที่ใช้ Android 14 ขึ้นไป) คุณต้องเพิ่มการตั้งค่าไฟล์ wrap.sh LD_HWASAN=1 ดูรายละเอียดเพิ่มเติมได้ใน เอกสารประกอบสำหรับนักพัฒนาแอป