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 จะไม่ส่งผลกระทบต่ออุปกรณ์