ดูข้อมูลเกี่ยวกับวิธีอ่านข้อขัดข้องของ 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 ดังนี้
- การล้น/การขาดบัฟเฟอร์สแต็กและฮีป
- การใช้งานฮีปหลังจากมีการปลดปล่อย
- การใช้สแต็กนอกขอบเขต
- ฟรีคู่/ฟรีแบบดุเดือด
นอกจากนี้ HWASan ยังตรวจหาการใช้สแต็กหลังจากการกลับมาด้วย
HWASan (เหมือนกับ ASan) เข้ากันได้กับ UBSan โดยเปิดใช้ได้พร้อมกันในเป้าหมาย
รายละเอียดและข้อจํากัดของการใช้งาน
HWASan อิงตามแนวทางการติดแท็กหน่วยความจำ ซึ่งค่าแท็กแบบสุ่มขนาดเล็กจะเชื่อมโยงกับทั้งตัวชี้และช่วงที่อยู่หน่วยความจำ เพื่อให้การเข้าถึงหน่วยความจำถูกต้อง แท็กพอยน์เตอร์และหน่วยความจำต้องตรงกัน HWASan อาศัยฟีเจอร์การละเว้นไบต์บนสุด (TBI) ของ ARMv8 หรือที่เรียกว่าการติดแท็กที่อยู่เสมือนเพื่อจัดเก็บแท็กพอยน์เตอร์ในบิตที่สูงที่สุดของที่อยู่
อ่านข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบของ HWASan ได้ในเว็บไซต์เอกสารประกอบของ Clang
โดยการออกแบบ HWASan จะไม่มีโซนสีแดงขนาดจำกัดของ ASan สำหรับตรวจหาการเขียนข้อมูลเกิน หรือพื้นที่กักเก็บที่มีขีดจำกัดของ ASan สำหรับตรวจหาการใช้งานหลังจากฟรี ด้วยเหตุนี้ HWASan จึงตรวจพบข้อบกพร่องได้ไม่ว่าหน่วยความจําจะล้นมากเพียงใดหรือมีการเรียกคืนหน่วยความจําไปนานเท่าใดก็ตาม ซึ่งทำให้ HWASan มีข้อได้เปรียบอย่างมากเมื่อเทียบกับ ASan
อย่างไรก็ตาม HWASan มีจำนวนค่าแท็กที่เป็นไปได้จํากัด (256) ซึ่งหมายความว่ามีโอกาส 0.4% ที่จะพลาดข้อบกพร่องในระหว่างการเรียกใช้โปรแกรม 1 ครั้ง
ข้อกำหนด
เคอร์เนล Android ทั่วไปเวอร์ชันล่าสุด (4.14 ขึ้นไป) รองรับ HWAS โดยตรง สาขาเฉพาะของ Android 10 ไม่รองรับ HWASan
การรองรับพื้นที่ผู้ใช้สําหรับ HWASan พร้อมใช้งานตั้งแต่ Android 11 เป็นต้นไป
หากคุณใช้เคอร์เนลอื่น HWASan จะกำหนดให้เคอร์เนล Linux ยอมรับพอยน์เตอร์ที่ติดแท็กในอาร์กิวเมนต์การเรียกระบบ เราได้รองรับการดำเนินการนี้ในชุดแพตช์จาก upstream ต่อไปนี้
- ABI ที่อยู่ที่ติดแท็ก arm64
- arm64: ยกเลิกการติดแท็กเคอร์เซอร์ผู้ใช้ที่ส่งไปยังเคอร์เนล
- mm: หลีกเลี่ยงการสร้างอีเมลแทนของที่อยู่เสมือนใน brk()/mmap()/mremap()
- arm64: ตรวจสอบที่อยู่ที่ติดแท็กใน access_ok() ที่เรียกจากเธรดเคอร์เนล
หากคุณสร้างด้วยชุดเครื่องมือที่กําหนดเอง ให้ตรวจสอบว่าชุดเครื่องมือมีทุกอย่างจนถึงคอมมิต LLVM 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 ครั้ง
- บิลด์แบบเพิ่มทีละน้อยใช้งานได้ทันที
- ไม่ต้องแฟลช 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()
ed mutex)
คุณไม่จําเป็นต้องเปลี่ยนไฟล์บิลด์ใดๆ หากแพลตฟอร์มทั้งหมดสร้างขึ้นโดยใช้ 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
ดูรายละเอียดเพิ่มเติมในเอกสารประกอบสำหรับนักพัฒนาแอป