Android รองรับเครื่องมือหลายอย่างสำหรับการแก้ไขข้อบกพร่องด้านหน่วยความจำ แต่ละวิธีมีข้อดีข้อเสียต่างกันไป ดังนั้นโปรดอ่านด้านล่างเพื่อตัดสินใจว่าวิธีใดเหมาะกับกรณีการใช้งานของคุณมากที่สุด เอกสารนี้จะแสดงภาพรวมของเครื่องมือที่มีให้ใช้งานเพื่อให้คุณตัดสินใจได้ว่าควรตรวจสอบเครื่องมือใดเพิ่มเติม แต่เราพยายามทำให้เอกสารนี้กระชับ ดังนั้นโปรดอ่านรายละเอียดในเอกสารของเครื่องมือแต่ละรายการ
สรุป
- ใช้ภาษาที่ปลอดภัยต่อหน่วยความจำทุกครั้งที่เป็นไปได้เพื่อไม่ให้ข้อผิดพลาดเกี่ยวกับหน่วยความจำเกิดขึ้น
- ใช้ PAC/BTI เสมอเพื่อลดการโจมตี ROP/JOP
- ใช้ GWP-ASan เสมอเพื่อตรวจหาข้อผิดพลาดด้านหน่วยความจำที่เกิดขึ้นไม่บ่อยในเวอร์ชันที่ใช้งานจริง
- ใช้ HWASan เพื่อตรวจหาข้อผิดพลาดด้านหน่วยความจําระหว่างการทดสอบ
- อุปกรณ์ที่รองรับ MTEยังไม่พร้อมให้บริการแก่ผู้ใช้ทั่วไป การดำเนินการนี้จะไม่มีประโยชน์จนกว่าจะมีการเปลี่ยนแปลง
- ใช้ ASan ในระหว่างการทดสอบเป็นทางเลือกสุดท้ายเท่านั้น
ภาษาที่ปลอดภัยต่อหน่วยความจำ
ภาษาที่ปลอดภัยสำหรับหน่วยความจำเป็นวิธีเดียวที่จะหลีกเลี่ยงและลดข้อผิดพลาดเกี่ยวกับหน่วยความจำได้ทั้งหมด เครื่องมืออื่นๆ ในหน้านี้จะช่วยทำให้โค้ดที่ไม่ปลอดภัยของหน่วยความจําปลอดภัยและน่าเชื่อถือมากขึ้น แต่การใช้ภาษาที่ไม่ปลอดภัยของหน่วยความจําจะขจัดปัญหาทั้งหมดในประเภทนี้ได้
ภาษาที่ปลอดภัยต่อหน่วยความจำซึ่งรองรับอย่างเป็นทางการสำหรับ Android ได้แก่ Java และ Kotlin แอปพลิเคชัน Android ส่วนใหญ่จะพัฒนาได้ง่ายกว่าในภาษาใดภาษาหนึ่งดังกล่าว
อย่างไรก็ตาม ยังมีนักพัฒนาแอปที่จัดส่งโค้ดที่เขียนด้วย Rust และหากคุณกำลังอ่านหน้านี้ คุณก็อาจมีเหตุผลอันสมควรที่ต้องใช้โค้ดเนทีฟ (ความสามารถในการใช้งานร่วมกัน ประสิทธิภาพ หรือทั้ง 2 อย่าง) Rust เป็นตัวเลือกที่ดีที่สุดสำหรับโค้ดเนทีฟที่ปลอดภัยต่อหน่วยความจำบน Android ทีม NDK อาจไม่สามารถช่วยคุณแก้ปัญหาที่คุณพบได้หากใช้เส้นทางดังกล่าว แต่เราสนใจที่จะทราบปัญหา
PAC/BTI
การตรวจสอบสิทธิ์ Pointer และระบุเป้าหมายสาขา หรือที่เรียกว่า PAC/BTI เป็นเครื่องมือบรรเทาความเสี่ยงที่เหมาะสำหรับใช้ในเวอร์ชันที่ใช้งานจริง แม้ว่าจะเป็นเทคโนโลยีที่แตกต่างกัน แต่ทั้ง 2 รายการนี้ควบคุมโดย Flag คอมไพเลอร์เดียวกัน จึงใช้ร่วมกันได้เสมอ
ฟีเจอร์เหล่านี้เข้ากันได้แบบย้อนหลังกับอุปกรณ์ที่ไม่รองรับ เนื่องจากวิธีการใหม่ที่ใช้จะใช้งานไม่ได้ในอุปกรณ์รุ่นเก่า นอกจากนี้ คุณยังต้องมีเคอร์เนลและระบบปฏิบัติการเวอร์ชันใหม่ด้วย
การค้นหา paca
และ bti
ใน /proc/cpuinfo
แสดงให้เห็นว่าคุณมีฮาร์ดแวร์ใหม่เพียงพอและเคอร์เนลใหม่เพียงพอหรือไม่ Android 12 (API 31) รองรับพื้นที่ผู้ใช้ที่จําเป็น
ข้อดี:
- เปิดใช้ได้ในทุกบิลด์โดยไม่ก่อให้เกิดปัญหาในอุปกรณ์หรือเคอร์เนลรุ่นเก่า (แต่อย่าลืมทดสอบกับอุปกรณ์/เคอร์เนล/ระบบปฏิบัติการที่รองรับจริงๆ)
ข้อเสีย:
- ใช้ได้กับแอป 64 บิตเท่านั้น
- ไม่ได้ลดข้อผิดพลาดในอุปกรณ์ที่ไม่รองรับ
- ค่าใช้จ่ายเพิ่มเติมเกี่ยวกับขนาดโค้ด 1%
GWP-Asan
GWP-ASan ใช้ตรวจหาข้อผิดพลาดด้านหน่วยความจําในฟิลด์ได้ แต่อัตราการสุ่มตัวอย่างต่ำเกินไปที่จะลดผลกระทบได้อย่างมีประสิทธิภาพ
ข้อดี:
- ไม่มีค่าใช้จ่ายเพิ่มเติมที่สำคัญของ CPU หรือหน่วยความจำ
- ใช้งานง่าย: ไม่ต้องสร้างโค้ดเนทีฟขึ้นมาใหม่
- ใช้ได้กับแอป 32 บิต
ข้อเสีย:
- อัตราการสุ่มตัวอย่างต่ำต้องใช้ผู้ใช้จํานวนมากเพื่อค้นหาข้อบกพร่องอย่างมีประสิทธิภาพ
- ตรวจหาเฉพาะข้อผิดพลาดของกอง โดยไม่ตรวจหาข้อผิดพลาดของสแต็ก
HWASan
โปรแกรมตรวจสอบที่อยู่ฮาร์ดแวร์หรือที่เรียกว่า HWASan เหมาะอย่างยิ่งในการจับข้อผิดพลาดด้านหน่วยความจําระหว่างการทดสอบ การตั้งค่านี้จะมีประโยชน์มากที่สุดเมื่อใช้กับการทดสอบอัตโนมัติ โดยเฉพาะในกรณีที่คุณทำการทดสอบ Fuzz แต่อาจใช้ได้กับโทรศัพท์ระดับสูงในการตั้งค่า "Dogfood" ด้วย ทั้งนี้ขึ้นอยู่กับความต้องการด้านประสิทธิภาพของแอป
ข้อดี:
- ไม่มีผลบวกลวง
- ตรวจหาข้อผิดพลาดเพิ่มเติมที่ ASan ตรวจไม่พบ (การใช้สแต็กหลังจากการคืนค่า)
- อัตราผลลบลวงต่ำกว่า MTE (1 ใน 256 เทียบกับ 1 ใน 16)
- มีการโอเวอร์เฮดของหน่วยความจําต่ำกว่า ASan ซึ่งเป็นทางเลือกที่ใกล้เคียงที่สุด
ข้อเสีย:
- มีการโอเวอร์เฮดของ CPU (~100%), ขนาดโค้ด (~50%) และหน่วยความจํา (10% - 35%) อย่างมาก
- ต้องใช้การแฟลชรูปภาพที่เข้ากันได้กับ HWASan จนถึง API 34 และ NDK r26
- ใช้ได้กับแอป 64 บิตเท่านั้น
MTE
ส่วนขยายการติดแท็กหน่วยความจําหรือที่เรียกว่า MTE เป็นทางเลือกที่มีต้นทุนต่ำกว่า HWASan นอกจากความสามารถในการแก้ไขข้อบกพร่องและการทดสอบแล้ว ยังใช้เพื่อตรวจหาและลดความเสียหายของหน่วยความจำในเวอร์ชันที่ใช้งานจริงได้ด้วย หากคุณมีฮาร์ดแวร์สำหรับทดสอบบิลด์ MTE คุณควรเปิดใช้ฟีเจอร์นี้
ข้อดี:
- ค่าใช้จ่ายเพิ่มเติมต่ำพอที่จะยอมรับได้ในเวอร์ชันที่ใช้งานจริงสำหรับแอปหลายแอป
- ไม่มีผลบวกลวง
- ไม่ต้องสร้างโค้ดใหม่เพื่อตรวจหาข้อผิดพลาดของกอง (แต่ต้องสร้างใหม่เพื่อตรวจหาข้อผิดพลาดของกองซ้อน)
ข้อเสีย:
- ในปี 2024 ไม่มีอุปกรณ์ที่พร้อมจำหน่ายซึ่งเปิดใช้ MTE โดยค่าเริ่มต้น แต่เอกสารประกอบของ Arm จะอธิบายวิธีเปิดใช้ MTE สำหรับการทดสอบใน Pixel 8/Pixel 8 Pro
- อัตราผลลบลวง 1 ใน 16 เทียบกับ 1 ใน 256 ของ HWASan
- ใช้ได้กับแอป 64 บิตเท่านั้น
- ต้องสร้างไลบรารีแยกต่างหากสําหรับการกําหนดเป้าหมายทั้งอุปกรณ์ที่เปิดใช้ MTE และที่เปิดใช้ MTE ไม่ได้
ASan
โปรแกรมตรวจสอบที่อยู่หรือที่รู้จักกันในชื่อ ASan เป็นเครื่องมือที่เก่าแก่ที่สุดและพร้อมใช้งานในวงกว้างที่สุด ซึ่งมีประโยชน์ในการจับข้อผิดพลาดเกี่ยวกับหน่วยความจำระหว่างการทดสอบและแก้ปัญหาการแก้ไขข้อบกพร่องที่ส่งผลกระทบต่ออุปกรณ์เก่าเท่านั้นซึ่งไม่มีเครื่องมืออื่นๆ ใดให้ใช้งาน หากเป็นไปได้ ให้ใช้ HWASan
ข้อดี:
- มีจำหน่ายทั่วไป อาจทำงานในอุปกรณ์รุ่นเก่าอย่าง KitKat ได้
- ไม่มีผลบวกลวงหรือผลลบลวงเมื่อใช้อย่างถูกต้อง
ข้อเสีย:
- สร้างและแพ็กเกจอย่างถูกต้องได้ยาก
- ค่าใช้จ่ายเพิ่มเติมสูงสุดของตัวเลือกทั้งหมด: CPU ~100%, ขนาดโค้ด ~50%, การใช้หน่วยความจํา ~100%
- ไม่รองรับอีกต่อไป
- มีข้อบกพร่องที่ทราบซึ่งจะไม่ได้รับการแก้ไข