การแก้ไขข้อบกพร่องและการลดข้อผิดพลาดด้านหน่วยความจํา

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%
  • ไม่รองรับอีกต่อไป
  • มีข้อบกพร่องที่ทราบซึ่งจะไม่ได้รับการแก้ไข