ดูข้อมูลเกี่ยวกับวิธีอ่านข้อขัดข้องของ 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 ดังนี้
- การล้น/การขาดบัฟเฟอร์สแต็กและฮีป
- การใช้ฮีปหลังจากฟรี
- การใช้สแต็กนอกขอบเขต
- Double Free/Wild Free
นอกจากนี้ HWASan ยังตรวจหาการใช้สแต็กหลังจากการกลับมาด้วย
HWASan (เช่นเดียวกับ ASan) ใช้ได้กับ UBSan คุณสามารถเปิดใช้ทั้ง 2 รายการในเป้าหมายได้พร้อมกัน
รายละเอียดและข้อจํากัดของการใช้งาน
HWASan ทำงานตามแนวทางการติดแท็กหน่วยความจำ ซึ่งค่าแท็กแบบสุ่มขนาดเล็กจะเชื่อมโยงกับทั้งตัวชี้และช่วงที่อยู่หน่วยความจำ เพื่อให้การเข้าถึงหน่วยความจำถูกต้อง แท็กพอยน์เตอร์และหน่วยความจำต้องตรงกัน HWASan อาศัยการละเว้นไบต์บนสุดของฟีเจอร์ ARMv8 (TBI) หรือที่เรียกว่าการติดแท็กที่อยู่เสมือน เพื่อจัดเก็บแท็กพอยน์เตอร์ในบิตที่สูงที่สุดของที่อยู่
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ การออกแบบ ของ 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 เพื่อยอมรับเคอร์เซอร์ที่ติดแท็กใน อาร์กิวเมนต์การเรียกระบบ มีการสนับสนุนสำหรับการอัปเดตนี้ในแพตช์อัปสตรีมต่อไปนี้:
- 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 ครั้ง
- บิลด์แบบเพิ่มทีละน้อยใช้งานได้ทันที
- ไม่จำเป็นต้องแสดงข้อมูลผู้ใช้แบบ Flash
ข้อจำกัดบางประการของ 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()
ใน 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
ใน
สร้าง หรือ -fsanitize=hwaddress
ในแฟล็กคอมไพเลอร์
ในอุปกรณ์ที่ไม่ใช่ HWASan (ที่ใช้ Android 14 ขึ้นไป) การตั้งค่าไฟล์ wrap.sh
ต้องเพิ่ม LD_HWASAN=1
โปรดดู
เอกสารประกอบสำหรับนักพัฒนาแอป
เพื่อดูรายละเอียดเพิ่มเติม