ShadowCallStack

ShadowCallStack (SCS) คือโหมด เครื่องมือวัด LLVM ที่ป้องกันการเขียนทับที่อยู่ผู้ส่ง (เช่น สแต็กบัฟเฟอร์โอเวอร์โฟลว์) โดยการบันทึกที่อยู่ผู้ส่งของฟังก์ชันไปยัง ShadowCallStack ที่จัดสรรแยกต่างหากใน prolog ฟังก์ชันของฟังก์ชัน nonleaf และโหลดที่อยู่ผู้ส่งจาก ShadowCallStack ในฟังก์ชัน บทส่งท้าย ที่อยู่ผู้ส่งจะถูกจัดเก็บไว้ในสแต็กปกติเพื่อให้เข้ากันได้กับเครื่องคลี่คลาย แต่ไม่มีการใช้งาน เพื่อให้แน่ใจว่าการโจมตีที่แก้ไขที่อยู่ผู้ส่งบนสแต็กปกติจะไม่ส่งผลต่อโฟลว์การควบคุมโปรแกรม

บน aarch64 เครื่องมือวัดใช้ประโยชน์จากรีจิสเตอร์ x18 เพื่ออ้างอิง ShadowCallStack ซึ่งหมายความว่าการอ้างอิง ShadowCallStack ไม่จำเป็นต้องจัดเก็บไว้ในหน่วยความจำ ซึ่งช่วยให้สามารถใช้รันไทม์เพื่อหลีกเลี่ยงการเปิดเผยที่อยู่ของ ShadowCallStack แก่ผู้โจมตีที่สามารถอ่านหน่วยความจำที่กำหนดเองได้

การนำไปปฏิบัติ

Android รองรับ ShadowCallStack สำหรับทั้งเคอร์เนลและพื้นที่ผู้ใช้

การเปิดใช้งาน SCS สำหรับเคอร์เนล

หากต้องการเปิดใช้งาน ShadowCallStack สำหรับเคอร์เนล ให้เพิ่มบรรทัดต่อไปนี้ลงในไฟล์กำหนดค่าเคอร์เนล:

CONFIG_SHADOW_CALL_STACK=y

การเปิดใช้งาน SCS ในพื้นที่ผู้ใช้

หากต้องการเปิดใช้งาน ShadowCallStack ในส่วนประกอบ userspace ให้เพิ่มบรรทัดต่อไปนี้ลงในไฟล์พิมพ์เขียวของส่วนประกอบ:

sanitize: {
  scs: true
}

SCS ถือว่าการลงทะเบียน x18 ได้รับการสงวนไว้เพื่อจัดเก็บที่อยู่ของ ShadowCallStack และไม่ได้ใช้เพื่อวัตถุประสงค์อื่นใด ในขณะที่ไลบรารีระบบทั้งหมดถูกคอมไพล์เพื่อจองการลงทะเบียน x18 นี่อาจเป็นปัญหาได้หากเปิดใช้งาน SCS สำหรับส่วนประกอบพื้นที่ผู้ใช้ที่ทำงานร่วมกับรหัสดั้งเดิมในกระบวนการ (ตัวอย่างเช่น ไลบรารีที่สามารถโหลดโดยแอปพลิเคชันของบริษัทอื่น) ซึ่งอาจปิดบัง การลงทะเบียน x18 ด้วยเหตุนี้ เราขอแนะนำให้เปิดใช้งาน SCS ในส่วนประกอบที่มีอยู่ในตัวเองซึ่งจะไม่ถูกโหลดลงในไบนารีแบบเดิมเท่านั้น

การตรวจสอบ

ไม่มีการทดสอบ CTS สำหรับ SCS โดยเฉพาะ โปรดตรวจสอบให้แน่ใจว่าการทดสอบ CTS ผ่านทั้งที่มีและไม่มีการเปิดใช้งาน SCS เพื่อตรวจสอบว่า SCS จะไม่ส่งผลกระทบต่ออุปกรณ์