ดู การทำความเข้าใจรายงาน HWASan สำหรับข้อมูลเกี่ยวกับวิธีการอ่าน HWASan ขัดข้อง!
AddressSanitizer ที่ใช้ฮาร์ดแวร์ช่วย (HWASan) เป็นเครื่องมือตรวจจับข้อผิดพลาดของหน่วยความจำที่คล้ายกับ AddressSanitizer HWASan ใช้ RAM น้อยกว่ามากเมื่อเทียบกับ ASan ซึ่งทำให้เหมาะสำหรับการฆ่าเชื้อทั้งระบบ HWASan ใช้ได้เฉพาะใน Android 10 ขึ้นไป และในฮาร์ดแวร์ AArch64 เท่านั้น
แม้ว่าจะมีประโยชน์สำหรับโค้ด C/C++ เป็นหลัก แต่ HWASan ยังสามารถช่วยดีบักโค้ด Java ที่ทำให้เกิดข้อขัดข้องใน C/C++ ที่ใช้ในการปรับใช้อินเทอร์เฟซ Java มีประโยชน์เพราะจะตรวจจับข้อผิดพลาดของหน่วยความจำเมื่อเกิดขึ้น โดยชี้ให้คุณเห็นรหัสที่รับผิดชอบโดยตรง
คุณสามารถแฟลชรูปภาพ HWASan ที่สร้างไว้ล่วงหน้าไปยังอุปกรณ์ Pixel ที่รองรับได้จาก ci.android.com ( คำแนะนำในการตั้งค่าโดยละเอียด )
เมื่อเทียบกับ ASan แบบคลาสสิก HWASan มี:
- โอเวอร์เฮด CPU ที่คล้ายกัน (~2x)
- ค่าโสหุ้ยขนาดรหัสที่คล้ายกัน (40 – 50%)
- โอเวอร์เฮด RAM ที่เล็กกว่ามาก (10% – 35%)
HWASan ตรวจพบบั๊กชุดเดียวกับ ASan:
- สแต็กและฮีปบัฟเฟอร์ล้น/อันเดอร์โฟลว์
- ใช้กองหลังฟรี
- ใช้สแต็คนอกขอบเขต
- ฟรีสองเท่า/ไวด์ฟรี
นอกจากนี้ HWASan ยังตรวจพบการใช้สแต็กหลังจากส่งคืน
HWASan (เหมือนกับ ASan) เข้ากันได้กับ UBSan ทั้งสองสามารถเปิดใช้งานบนเป้าหมายได้พร้อมกัน
รายละเอียดการใช้งานและข้อจำกัด
HWASan อิงตามวิธีการ ติดแท็กหน่วยความจำ โดยที่ค่าแท็กสุ่มขนาดเล็กจะเชื่อมโยงกับตัวชี้และช่วงที่อยู่หน่วยความจำ เพื่อให้การเข้าถึงหน่วยความจำถูกต้อง ตัวชี้และแท็กหน่วยความจำต้องตรงกัน HWASan อาศัย ARMv8 ฟีเจอร์การละเว้นไบต์บนสุด (TBI) หรือเรียกอีกอย่างว่าการ ติดแท็กที่อยู่เสมือน เพื่อเก็บแท็กตัวชี้ในบิตสูงสุดของที่อยู่
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ การออกแบบ HWASan ได้จากเว็บไซต์เอกสาร Clang
ตามการออกแบบ HWASan ไม่มีโซนสีแดงที่มีขนาดจำกัดของ ASan สำหรับตรวจจับการล้นหรือการกักกันที่มีความจุจำกัดของ ASan สำหรับการตรวจจับการใช้งานหลังจากใช้งานฟรี ด้วยเหตุผลนี้ HWASan จึงสามารถตรวจจับจุดบกพร่องได้ไม่ว่าโอเวอร์โฟลว์จะมีขนาดใหญ่เพียงใดหรือหน่วยความจำจะถูกจัดสรรคืนมานานแค่ไหน สิ่งนี้ทำให้ HWASan ได้เปรียบเหนือ ASan อย่างมาก
อย่างไรก็ตาม HWASan มีค่าแท็กที่เป็นไปได้ในจำนวนจำกัด (256) ซึ่งหมายความว่ามีความเป็นไปได้ 0.4% ที่จะพลาดจุดบกพร่องใดๆ ในระหว่างการเรียกใช้โปรแกรมหนึ่งครั้ง
ความต้องการ
เวอร์ชันล่าสุด (4.14+) ของ เคอร์เนล Android ทั่วไป รองรับ HWASan ที่พร้อมใช้งานทันที สาขาเฉพาะของ Android 10 ไม่รองรับ HWASan
รองรับ Userspace สำหรับ HWASan โดยเริ่มตั้งแต่ Android 11
หากคุณกำลังทำงานกับเคอร์เนลอื่น HWASan ต้องการให้เคอร์เนล Linux ยอมรับพอยน์เตอร์ที่ติดแท็กในอาร์กิวเมนต์การเรียกระบบ การสนับสนุนสำหรับสิ่งนี้ถูกนำมาใช้ในแพตช์อัปสตรีมต่อไปนี้:
- arm64 ที่อยู่ที่แท็ก ABI
- arm64: ยกเลิกการแท็กพอยน์เตอร์ผู้ใช้ที่ส่งไปยังเคอร์เนล
- mm: หลีกเลี่ยงการสร้างนามแฝงที่อยู่เสมือนใน brk()/mmap()/mremap()
- arm64: ตรวจสอบที่อยู่ที่ติดแท็กใน access_ok() ที่เรียกจากเคอร์เนล threads
หากคุณกำลังสร้างด้วย 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 ความซับซ้อนในการสร้างหายไปมากมาย:
- ไม่จำเป็นต้องวิ่งสองครั้ง
- บิลด์ที่เพิ่มขึ้นทำงานนอกกรอบ
- ไม่จำเป็นต้องแฟลชข้อมูลผู้ใช้
ข้อจำกัด 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 ที่ปลดล็อกโปรแกรมโหลดบูตได้โดยใช้ Flashstation เลือกเป้าหมาย _hwasan เช่น aosp_flame_hwasan-userdebug ดู เอกสารประกอบ NDK สำหรับ HWASan สำหรับนักพัฒนาแอปสำหรับรายละเอียดเพิ่มเติม
การติดตามสแต็กที่ดีขึ้น
HWASan ใช้ตัวคลายตัวแบบอิงเฟรมอย่างรวดเร็วเพื่อบันทึกสแต็กเทรซสำหรับทุกๆ เหตุการณ์การจัดสรรหน่วยความจำและการจัดสรรคืนในโปรแกรม Android เปิดใช้งานตัวชี้เฟรมในโค้ด AArch64 โดยค่าเริ่มต้น ดังนั้นจึงใช้งานได้ดีในทางปฏิบัติ หากคุณต้องการคลายโค้ดที่ได้รับการจัดการ ให้ตั้งค่า HWASAN_OPTIONS=fast_unwind_on_malloc=0
ในสภาพแวดล้อมกระบวนการ โปรดทราบว่าการติดตามสแต็กการเข้าถึงหน่วยความจำที่ไม่ดีใช้ตัวคลาย "ช้า" โดยค่าเริ่มต้น การตั้งค่านี้มีผลกับการติดตามการจัดสรรและการจัดสรรคืนเท่านั้น ตัวเลือกนี้อาจใช้ CPU มาก ขึ้นอยู่กับโหลด
สัญลักษณ์
ดู สัญลักษณ์ ใน "การทำความเข้าใจรายงาน HWASan"
HWASan ในแอป
คล้ายกับ AddressSanitizer HWASan ไม่สามารถมองเห็นโค้ด Java ได้ แต่สามารถตรวจจับจุดบกพร่องในไลบรารี JNI ได้ ไม่สนับสนุน ASan การเรียกใช้แอป HWASan บนอุปกรณ์ที่ ไม่ใช่ HWASan
บนอุปกรณ์ HWASan แอปสามารถตรวจสอบกับ HWASan ได้โดยการสร้างโค้ดด้วย SANITIZE_TARGET:=hwaddress
ใน Make หรือ -fsanitize=hwaddress
ในแฟล็กคอมไพเลอร์ ดู เอกสารสำหรับนักพัฒนาแอป สำหรับรายละเอียดเพิ่มเติม
ดู การทำความเข้าใจรายงาน HWASan สำหรับข้อมูลเกี่ยวกับวิธีการอ่าน HWASan ขัดข้อง!
AddressSanitizer ที่ใช้ฮาร์ดแวร์ช่วย (HWASan) เป็นเครื่องมือตรวจจับข้อผิดพลาดของหน่วยความจำที่คล้ายกับ AddressSanitizer HWASan ใช้ RAM น้อยกว่ามากเมื่อเทียบกับ ASan ซึ่งทำให้เหมาะสำหรับการฆ่าเชื้อทั้งระบบ HWASan ใช้ได้เฉพาะใน Android 10 ขึ้นไป และในฮาร์ดแวร์ AArch64 เท่านั้น
แม้ว่าจะมีประโยชน์สำหรับโค้ด C/C++ เป็นหลัก แต่ HWASan ยังสามารถช่วยดีบักโค้ด Java ที่ทำให้เกิดข้อขัดข้องใน C/C++ ที่ใช้ในการปรับใช้อินเทอร์เฟซ Java มีประโยชน์เพราะจะตรวจจับข้อผิดพลาดของหน่วยความจำเมื่อเกิดขึ้น โดยชี้ให้คุณเห็นรหัสที่รับผิดชอบโดยตรง
คุณสามารถแฟลชรูปภาพ HWASan ที่สร้างไว้ล่วงหน้าไปยังอุปกรณ์ Pixel ที่รองรับได้จาก ci.android.com ( คำแนะนำในการตั้งค่าโดยละเอียด )
เมื่อเทียบกับ ASan แบบคลาสสิก HWASan มี:
- โอเวอร์เฮด CPU ที่คล้ายกัน (~2x)
- ค่าโสหุ้ยขนาดรหัสที่คล้ายกัน (40 – 50%)
- โอเวอร์เฮด RAM ที่เล็กกว่ามาก (10% – 35%)
HWASan ตรวจพบบั๊กชุดเดียวกับ ASan:
- สแต็กและฮีปบัฟเฟอร์ล้น/อันเดอร์โฟลว์
- ใช้กองหลังฟรี
- ใช้สแต็คนอกขอบเขต
- ฟรีสองเท่า/ไวด์ฟรี
นอกจากนี้ HWASan ยังตรวจพบการใช้สแต็กหลังจากส่งคืน
HWASan (เหมือนกับ ASan) เข้ากันได้กับ UBSan ทั้งสองสามารถเปิดใช้งานบนเป้าหมายได้พร้อมกัน
รายละเอียดการใช้งานและข้อจำกัด
HWASan อิงตามวิธีการ ติดแท็กหน่วยความจำ โดยที่ค่าแท็กสุ่มขนาดเล็กจะเชื่อมโยงกับตัวชี้และช่วงที่อยู่หน่วยความจำ เพื่อให้การเข้าถึงหน่วยความจำถูกต้อง ตัวชี้และแท็กหน่วยความจำต้องตรงกัน HWASan อาศัย ARMv8 ฟีเจอร์การละเว้นไบต์บนสุด (TBI) หรือเรียกอีกอย่างว่าการ ติดแท็กที่อยู่เสมือน เพื่อเก็บแท็กตัวชี้ในบิตสูงสุดของที่อยู่
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ การออกแบบ HWASan ได้จากเว็บไซต์เอกสาร Clang
ตามการออกแบบ HWASan ไม่มีโซนสีแดงที่มีขนาดจำกัดของ ASan สำหรับตรวจจับการล้นหรือการกักกันที่มีความจุจำกัดของ ASan สำหรับการตรวจจับการใช้งานหลังจากใช้งานฟรี ด้วยเหตุผลนี้ HWASan จึงสามารถตรวจจับจุดบกพร่องได้ไม่ว่าโอเวอร์โฟลว์จะมีขนาดใหญ่เพียงใดหรือหน่วยความจำจะถูกจัดสรรคืนมานานแค่ไหน สิ่งนี้ทำให้ HWASan ได้เปรียบเหนือ ASan อย่างมาก
อย่างไรก็ตาม HWASan มีค่าแท็กที่เป็นไปได้ในจำนวนจำกัด (256) ซึ่งหมายความว่ามีความเป็นไปได้ 0.4% ที่จะพลาดจุดบกพร่องใดๆ ในระหว่างการเรียกใช้โปรแกรมหนึ่งครั้ง
ความต้องการ
เวอร์ชันล่าสุด (4.14+) ของ เคอร์เนล Android ทั่วไป รองรับ HWASan ที่พร้อมใช้งานทันที สาขาเฉพาะของ Android 10 ไม่รองรับ HWASan
รองรับ Userspace สำหรับ HWASan โดยเริ่มตั้งแต่ Android 11
หากคุณกำลังทำงานกับเคอร์เนลอื่น HWASan ต้องการให้เคอร์เนล Linux ยอมรับพอยน์เตอร์ที่ติดแท็กในอาร์กิวเมนต์การเรียกระบบ การสนับสนุนสำหรับสิ่งนี้ถูกนำมาใช้ในแพตช์อัปสตรีมต่อไปนี้:
- arm64 ที่อยู่ที่แท็ก ABI
- arm64: ยกเลิกการแท็กพอยน์เตอร์ผู้ใช้ที่ส่งไปยังเคอร์เนล
- mm: หลีกเลี่ยงการสร้างนามแฝงที่อยู่เสมือนใน brk()/mmap()/mremap()
- arm64: ตรวจสอบที่อยู่ที่ติดแท็กใน access_ok() ที่เรียกจากเคอร์เนล threads
หากคุณกำลังสร้างด้วย 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 ความซับซ้อนในการสร้างหายไปมากมาย:
- ไม่จำเป็นต้องวิ่งสองครั้ง
- บิลด์ที่เพิ่มขึ้นทำงานนอกกรอบ
- ไม่จำเป็นต้องแฟลชข้อมูลผู้ใช้
ข้อจำกัด 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 ที่ปลดล็อกโปรแกรมโหลดบูตได้โดยใช้ Flashstation เลือกเป้าหมาย _hwasan เช่น aosp_flame_hwasan-userdebug ดู เอกสารประกอบ NDK สำหรับ HWASan สำหรับนักพัฒนาแอปสำหรับรายละเอียดเพิ่มเติม
การติดตามสแต็กที่ดีขึ้น
HWASan ใช้ตัวคลายตัวแบบอิงเฟรมอย่างรวดเร็วเพื่อบันทึกสแต็กเทรซสำหรับทุกๆ เหตุการณ์การจัดสรรหน่วยความจำและการจัดสรรคืนในโปรแกรม Android เปิดใช้งานตัวชี้เฟรมในโค้ด AArch64 โดยค่าเริ่มต้น ดังนั้นจึงใช้งานได้ดีในทางปฏิบัติ หากคุณต้องการคลายโค้ดที่ได้รับการจัดการ ให้ตั้งค่า HWASAN_OPTIONS=fast_unwind_on_malloc=0
ในสภาพแวดล้อมกระบวนการ โปรดทราบว่าการติดตามสแต็กการเข้าถึงหน่วยความจำที่ไม่ดีใช้ตัวคลาย "ช้า" โดยค่าเริ่มต้น การตั้งค่านี้มีผลกับการติดตามการจัดสรรและการจัดสรรคืนเท่านั้น ตัวเลือกนี้อาจใช้ CPU มาก ขึ้นอยู่กับโหลด
สัญลักษณ์
ดู สัญลักษณ์ ใน "การทำความเข้าใจรายงาน HWASan"
HWASan ในแอป
คล้ายกับ AddressSanitizer HWASan ไม่สามารถมองเห็นโค้ด Java ได้ แต่สามารถตรวจจับจุดบกพร่องในไลบรารี JNI ได้ ไม่สนับสนุน ASan การเรียกใช้แอป HWASan บนอุปกรณ์ที่ ไม่ใช่ HWASan
บนอุปกรณ์ HWASan แอปสามารถตรวจสอบกับ HWASan ได้โดยการสร้างโค้ดด้วย SANITIZE_TARGET:=hwaddress
ใน Make หรือ -fsanitize=hwaddress
ในแฟล็กคอมไพเลอร์ ดู เอกสารสำหรับนักพัฒนาแอป สำหรับรายละเอียดเพิ่มเติม