2 คะแนน โดย GN⁺ 2024-10-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

เจาะลึก system call mseal ใหม่ของ Linux

  • mseal เป็น system call ใหม่ที่ถูกเพิ่มเข้ามาใน Linux kernel เวอร์ชัน 6.10 โดยมอบความสามารถ "ปิดผนึกหน่วยความจำ" เพื่อการปกป้องหน่วยความจำ
  • system call นี้ทำให้พื้นที่หน่วยความจำไม่เปลี่ยนแปลงจากการแก้ไขที่ไม่ชอบด้วยกฎหมายระหว่างการทำงานของโปรแกรม ทำให้ผู้โจมตีไม่สามารถเปลี่ยนสิทธิ์ของหน่วยความจำหรือบิดเบือน layout ของหน่วยความจำได้
  • mseal มีเป้าหมายเพื่อป้องกันการรันโค้ดของผู้โจมตีระยะไกล ซึ่งแตกต่างจาก memfd_create และ memfd_secret ที่มีอยู่เดิมซึ่งใช้ป้องกันผู้โจมตีในเครื่องที่เก็บข้อมูลอ่อนไหวไว้ในหน่วยความจำ

วิธีการทำงานของ mseal

  • ฟังก์ชันซิกเนเจอร์ของ mseal เรียบง่าย โดยรับค่าเริ่มต้นของ address และความยาวเพื่อปิดผนึกพื้นที่หน่วยความจำนั้น
  • ฟังก์ชัน do_mseal จะล็อกพื้นที่หน่วยความจำ และตรวจสอบความถูกต้องรวมถึงปิดผนึกพื้นที่หน่วยความจำผ่าน check_mm_seal และ apply_mm_seal
  • พื้นที่หน่วยความจำที่ถูกปิดผนึกแล้วจะไม่สามารถเปลี่ยนสิทธิ์ ยกเลิกการแมป หรือปรับขนาดได้ผ่าน system call เช่น mprotect, munmap, mremap เป็นต้น

เทคนิคการโจมตีที่ mseal ป้องกันได้

  • การเสริมความแข็งแกร่งให้ NX: mseal ป้องกันไม่ให้มีการเปลี่ยนสิทธิ์การรันของ VMA จึงช่วยป้องกันการโจมตีที่อาศัย shellcode
  • บรรเทาการโจมตีแบบ data-only ที่อาศัยการ unmap: mseal ป้องกันการยกเลิกการแมปและการรีแมปพื้นที่หน่วยความจำตามอำเภอใจ จึงช่วยหยุดการโจมตีแบบ data-only

การใช้ mseal เพื่อเพิ่มความแข็งแกร่งให้ซอฟต์แวร์

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

สรุปโดย GN⁺

  • mseal เป็นฟีเจอร์ด้านความปลอดภัยใหม่ที่ถูกเพิ่มเข้ามาใน Linux kernel โดยป้องกันการรันโค้ดของผู้โจมตีระยะไกลผ่านการปิดผนึกพื้นที่หน่วยความจำ
  • system call นี้ต่างจากแนวทางปกป้องหน่วยความจำแบบเดิม เพราะมันป้องกันทั้งการเปลี่ยนสิทธิ์ของหน่วยความจำและการยกเลิกการแมป จึงช่วยป้องกันการโจมตีแบบ data-only
  • การมาถึงของ mseal มีบทบาทสำคัญต่อการยกระดับความปลอดภัยของซอฟต์แวร์ และคาดว่าจะมีกรณีใช้งานเพิ่มขึ้นผ่านการผสานรวมกับ glibc
  • โปรเจ็กต์อื่นที่มีความสามารถคล้ายกันได้แก่ memfd_create และ memfd_secret สำหรับการปกป้องหน่วยความจำ

1 ความคิดเห็น

 
GN⁺ 2024-10-27
ความคิดเห็นใน Hacker News
  • มีความเห็นหนึ่งกล่าวถึง "การถกเถียงที่ดุเดือด" ในเคอร์เนลเมลลิงลิสต์ และสงสัยว่ามีคนวงในพอจะสรุปข้อคัดค้านและข้อกังวลได้หรือไม่ โดยปกติมักหลีกเลี่ยงเมลลิงลิสต์เพราะบรรยากาศเข้มข้นเกินไป

    • ตัวกลไกเองดูสมเหตุสมผล แต่ก็น่าแปลกใจที่ยังไม่มีอยู่ในเคอร์เนลมาก่อน
  • Chrome ต้องการใช้ syscall นี้ แต่ไม่สามารถยกเลิกการผนึกหน้าเพจที่ถูกซีลได้ เพราะผู้โจมตีสามารถ remap ใหม่ด้วยแฟลกอื่นได้

    • นั่นหมายความว่าไม่สามารถใช้กับเพจที่จัดสรรตอนรันไทม์ได้ และใช้ไม่ได้ เว้นแต่ตั้งใจจะถือมันไว้ตลอดอายุของโปรเซส
    • มีคำถามตามมาว่านี่หมายความว่าใช้กับหน่วยความจำอย่าง JS sandbox ไม่ได้ใช่หรือไม่
    • ผู้แสดงความเห็นไม่คุ้นเคยกับวิธีที่ Chrome จัดการหน่วยความจำ/โปรเซสมากพอ จึงไม่แน่ใจว่าทำไมเรื่องนี้ถึงไม่เป็นปัญหา
  • มีการให้ลิงก์ไปยัง mseal() และบทความที่ตามมา

  • มีความรู้สึกเสียดายที่แม้สถาปัตยกรรมสมัยใหม่อย่าง (x86_64) จะมีฟีเจอร์มากมายที่ส่งเสริมการเขียนโปรแกรมอย่างปลอดภัย แต่ระบบปฏิบัติการก็ยังต้องมาเพิ่ม syscall ลักษณะนี้

    • ความพยายามในการแพตช์ระบบเก่าเป็นการฉุดรั้งความก้าวหน้าของการประมวลผลและทำให้ผู้คนนับพันล้านตกอยู่ในความเสี่ยง
    • แม้จะมีบั๊กในระดับสถาปัตยกรรมอยู่บ้าง แต่ซอฟต์แวร์ก็ยังใช้ประโยชน์จากความสามารถที่มีอยู่ในปัจจุบันได้ไม่ดีพอ
  • มีคำถามว่าสามารถทำให้ mseal system call ใช้การไม่ได้ด้วยลูกเล่น LD_PRELOAD หรือไม่

  • โปรโตไทป์ของ mseal() ในบทความไม่ถูกต้องตามไวยากรณ์ อาร์กิวเมนต์ตัวแรกควรเป็น unsigned long start_addr ไม่ใช่ unsigned start addr

  • OpenBSD มีความสามารถนี้มานานแล้ว จึงมีการตั้งคำถามว่าทำไม Linux เพิ่งจะนำมาใช้ตอนนี้