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

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

AddressSanitizer (HWASan) ที่ใช้ฮาร์ดแวร์ช่วยเป็นข้อผิดพลาดของหน่วยความจํา เครื่องมือตรวจจับที่คล้ายกับ AddressSanitizer ฮวาซาน ใช้ 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 คุณสามารถเปิดใช้ทั้ง 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 เพื่อยอมรับเคอร์เซอร์ที่ติดแท็กใน อาร์กิวเมนต์การเรียกระบบ เราได้ติดตั้งใช้งานการรองรับการดำเนินการนี้ในชุดแพตช์จาก upstream ต่อไปนี้

หากคุณสร้างด้วย Toolchain ที่กำหนดเอง โปรดตรวจสอบว่าได้รวมทุกอย่างจนถึง 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 ครั้ง
  • บิลด์แบบเพิ่มทีละน้อยใช้งานได้ทันที
  • ไม่จำเป็นต้องแสดงข้อมูลผู้ใช้แบบ 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_flae_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 ดูรายละเอียดเพิ่มเติมในเอกสารประกอบสำหรับนักพัฒนาแอป