AddressSanitizer ที่ใช้ฮาร์ดแวร์ช่วย

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

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

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

คุณสามารถแฟลชภาพ HWASan ที่คอมไพล์ไว้ล่วงหน้าลงในอุปกรณ์ Pixel ที่รองรับได้จาก ci.android.com (วิธีการตั้งค่าโดยละเอียด)

HWASan มีคุณสมบัติต่อไปนี้เมื่อเทียบกับ ASan คลาสสิก

  • ภาระงานของ CPU ที่คล้ายกัน (~2 เท่า)
  • ค่าใช้จ่ายเพิ่มเติมเกี่ยวกับขนาดโค้ดที่คล้ายกัน (40 – 50%)
  • โอเวอร์เฮดของ RAM น้อยลงมาก (10% – 35%)

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

  • การล้น/การขาดบัฟเฟอร์ของกองและกอง heap
  • การใช้งานฮีปหลังจากมีการปลดปล่อย
  • การใช้สแต็กนอกขอบเขต
  • ฟรีแบบคู่/ฟรีแบบไม่มีเงื่อนไข

นอกจากนี้ HWASan ยังตรวจหาการใช้สแต็กหลังจากการกลับมาด้วย

HWASan (เหมือนกับ ASan) ใช้งานได้กับ UBSan โดยทั้ง 2 ฟีเจอร์จะเปิดใช้ในเป้าหมายพร้อมกันได้

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

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

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

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

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

ข้อกำหนด

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

การรองรับพื้นที่ผู้ใช้สำหรับ HWASan จะพร้อมให้บริการใน Android 11

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

หากคุณกำลังสร้างด้วยชุดเครื่องมือที่กําหนดเอง ให้ตรวจสอบว่าชุดเครื่องมือมีทุกอย่างจนถึงคอมมิต LLVM c336557f

ใช้ HWASan

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

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

คุณสามารถเพิ่มการตั้งค่า SANITIZE_TARGET ลงในคําจํากัดความของผลิตภัณฑ์เพื่อเพิ่มความสะดวกได้ ซึ่งคล้ายกับ aosp_coral_hwasan

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

  • ไม่จำเป็นต้องรัน 2 ครั้ง
  • บิลด์แบบเพิ่มทีละน้อยใช้งานได้ทันที
  • ไม่ต้องแฟลช userdata

ข้อจํากัดบางอย่างของ AddressSanitizer จะไม่มีอยู่อีกต่อไปด้วย

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

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

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

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

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

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

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

FlashStation

หากมีไว้เพื่อการพัฒนา คุณอาจแฟลช AOSP รุ่นที่เปิดใช้ HWASan ลงในอุปกรณ์ Pixel ที่มี Bootloader ที่ปลดล็อกโดยใช้ Flashstation เลือกเป้าหมาย _hwasan เช่น aosp_flame_hwasan-userdebug ดูรายละเอียดเพิ่มเติมได้ที่เอกสารประกอบ NDK ของ HWASan สำหรับนักพัฒนาแอป

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

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

การใช้สัญลักษณ์

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

HWASan ในแอป

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

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