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


19

เมื่อ CPU อยู่ในโหมดผู้ใช้ CPU จะไม่สามารถประมวลผลคำแนะนำพิเศษและไม่สามารถเข้าถึงหน่วยความจำพื้นที่เคอร์เนลได้

และเมื่อ CPU อยู่ในโหมดเคอร์เนล CPU สามารถดำเนินการคำสั่งทั้งหมดและสามารถเข้าถึงหน่วยความจำทั้งหมด

ตอนนี้ใน Linux โปรแกรมโหมดผู้ใช้สามารถเข้าถึงหน่วยความจำทั้งหมด (โดยใช้/dev/mem) และสามารถดำเนินการตามคำแนะนำพิเศษสองอย่างINและOUT(โดยใช้iopl()ฉันคิดว่า)

ดังนั้นโปรแกรมโหมดผู้ใช้ใน Linux สามารถทำสิ่งต่าง ๆ ได้ (ฉันคิดว่าเกือบทุกอย่าง) ซึ่งสามารถทำได้ในโหมดเคอร์เนล

ไม่อนุญาตให้โปรแกรมโหมดผู้ใช้ใช้พลังงานทั้งหมดนี้เพื่อวัตถุประสงค์ในการมีโหมด CPU หรือไม่

คำตอบ:


23

ดังนั้นโปรแกรมโหมดผู้ใช้ใน Linux สามารถทำสิ่งต่าง ๆ ได้ (ฉันคิดว่าเกือบทุกอย่าง) ซึ่งสามารถทำได้ในโหมดเคอร์เนล

ไม่ใช่ว่าทุกโหมดผู้ใช้สามารถทำได้เฉพาะโปรแกรมที่มีสิทธิ์ที่เหมาะสม และที่กำหนดโดยเคอร์เนล

/dev/memได้รับการคุ้มครองโดยสิทธิ์การเข้าถึงระบบไฟล์ตามปกติและCAP_SYS_RAWIOความสามารถ iopl()และioperm()ถูก จำกัด ด้วยความสามารถเดียวกัน

/dev/memสามารถรวบรวมได้จากเคอร์เนลทั้งหมด ( CONFIG_DEVMEM)

ไม่อนุญาตให้โปรแกรมโหมดผู้ใช้ใช้พลังงานทั้งหมดนี้เพื่อวัตถุประสงค์ในการมีโหมด CPU หรือไม่

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

(นอกจากนี้ยังมีความจริงที่iopl()ทำงานโดยใช้โหมดสิทธิ์ซีพียูใน i386 ดังนั้นจึงไม่สามารถกล่าวได้ว่าเอาชนะวัตถุประสงค์ของพวกเขาได้อย่างดี)


2
แม้ioplจะไม่อนุญาตให้มีคำแนะนำพิเศษทั้งหมดดังนั้นจึงยังมีประโยชน์สำหรับการตรวจสอบให้แน่ใจว่าโปรแกรมพื้นที่ผู้ใช้แบบบั๊กไม่ได้ตั้งใจทำงานinvdโดยการกระโดดผ่านตัวชี้ฟังก์ชั่นที่เสียหายซึ่งชี้ไปที่หน่วยความจำปฏิบัติการที่เริ่มต้นด้วย0F 08ไบต์ ฉันได้เพิ่มคำตอบด้วยเหตุผลที่ไม่เกี่ยวกับความปลอดภัยว่าทำไมจึงมีประโยชน์ที่จะให้กระบวนการผู้ใช้พื้นที่ยกระดับสิทธิ์ของพวกเขา
Peter Cordes

16

ในลักษณะเดียวกับที่modprobe"เอาชนะ" ความปลอดภัยโดยการโหลดรหัสใหม่ลงในเคอร์เนล

ด้วยเหตุผลต่าง ๆ บางครั้งมันก็สมเหตุสมผลที่จะมีโค้ดกึ่งสิทธิพิเศษ (เช่นไดรเวอร์กราฟิกภายในเซิร์ฟเวอร์ X) ที่ทำงานในพื้นที่ผู้ใช้แทนที่จะเป็นเคอร์เนลเธรด

  • ความสามารถในการทำได้killง่ายขึ้นเว้นแต่จะล็อคค่า HW
  • มีมันต้องการหน้ารหัส / ข้อมูลจากไฟล์ในระบบแฟ้ม (หน่วยความจำเคอร์เนลไม่สามารถเพจได้)
  • ให้พื้นที่ที่อยู่เสมือนของตนเองซึ่งมีข้อบกพร่องในเซิร์ฟเวอร์ X อาจทำให้เซิร์ฟเวอร์ X ผิดพลาดโดยไม่ทำให้เคอร์เนลเสียหาย

มันไม่ได้ทำอะไรมากสำหรับเรื่องความปลอดภัย แต่ก็มีข้อได้เปรียบที่น่าเชื่อถือและสถาปัตยกรรมซอฟต์แวร์

การอบไดรเวอร์กราฟิกส์ลงในเคอร์เนลอาจลดการสลับบริบทระหว่างไคลเอนต์ X และเซิร์ฟเวอร์ X เช่นผู้ใช้เพียงคนเดียว - ผู้ใช้เคอร์เนล> แทนที่จะต้องดึงข้อมูลเข้าสู่กระบวนการใช้พื้นที่อื่น แต่เซิร์ฟเวอร์ X ในอดีตมีขนาดใหญ่เกินไป ต้องการให้เต็มในเคอร์เนล


ใช่โค้ดที่เป็นอันตรายซึ่งมี privs เหล่านี้อาจเข้าควบคุมเคอร์เนลได้หากต้องการใช้/dev/memเพื่อแก้ไขโค้ดเคอร์เนล

หรือบน x86 ให้รันcliคำสั่งเพื่อปิดใช้งานอินเตอร์รัปต์บนคอร์นั้นหลังจากทำการioplเรียกระบบเพื่อตั้งค่าระดับสิทธิ์ของ IO เป็นแหวน 0

แต่แม้แต่ x86 iopl"เท่านั้น" ก็ให้การเข้าถึงคำสั่งบางอย่าง : เข้า / ออก (และรุ่นสตริง ins / outs) และ cli / sti มันไม่อนุญาตให้คุณใช้rdmsrหรือwrmsrอ่านหรือเขียน "model specific register" (เช่นIA32_LSTARซึ่งตั้งค่าที่อยู่จุดเข้าเคอร์เนลสำหรับsyscallคำสั่งx86-64 ) หรือใช้lidtเพื่อแทนที่ตาราง interrupt-descriptor (ซึ่งจะช่วยให้คุณใช้ทั้งหมด อยู่เหนือเครื่องจากเคอร์เนลที่มีอยู่อย่างน้อยในคอร์นั้น)

คุณไม่สามารถอ่านแม้กระทั่งการลงทะเบียนการควบคุม (เช่น CR3 ซึ่งถือที่อยู่ทางกายภาพของระดับบนหน้าไดเรกทอรีซึ่งกระบวนการโจมตีอาจพบว่ามีประโยชน์เป็นชดเชยเป็น/dev/memที่จะปรับเปลี่ยนตารางหน้าของตัวเองเป็นทางเลือกให้ไอเอ็นจีมากขึ้นของmmap /dev/mem)

invd(ทำให้แคชทั้งหมดไม่ถูกต้องโดยไม่ต้องเขียนกลับ !! ( ใช้ case = BIOS ก่อนหน้านี้ก่อนกำหนดค่า RAM)) เป็นอีกหนึ่งความสนุกที่ต้องใช้ CPL 0 เต็ม (ระดับสิทธิ์ปัจจุบัน) ไม่ใช่แค่ IOPL แม้จะwbinvdเป็นสิทธิพิเศษเพราะมันช้าดังนั้น (และไม่ Interruptible) และมีการล้างทุกศาสนาทั่วแกนทั้งหมด (ดูมีวิธีล้าง CPU แคชทั้งหมดที่เกี่ยวข้องกับโปรแกรมหรือไม่และการใช้งานคำสั่ง WBINVD )

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


ระดับสิทธิพิเศษในปัจจุบัน (ในโหมดการป้องกันและระยะยาว) คือต่ำ 2 บิตcs (ตัวเลือกส่วนของรหัส) mov eax, cs/ and eax, 3ทำงานในโหมดใดก็ได้เพื่ออ่านระดับสิทธิ์

ในการเขียนระดับสิทธิ์คุณต้องทำjmp farหรือcall farเพื่อตั้งค่าCS:RIP(แต่รายการ GDT / LDT สำหรับกลุ่มเป้าหมายสามารถ จำกัด ได้ตามระดับสิทธิ์เก่าซึ่งเป็นสาเหตุที่พื้นที่ผู้ใช้ไม่สามารถทำได้เพื่อยกระดับตัวเอง) หรือคุณใช้intหรือsyscallเพื่อเปลี่ยนเป็นแหวน 0 ที่จุดเข้าใช้เคอร์เนล


ที่จริงฉันค่อนข้างมั่นใจว่าเป็นเพียงรหัส "ตัวเลือก" ใน Intel parlace มันเป็นเซ็กเมนต์ใน 8086/8088 อาจเป็นใน 80186 แต่โดย 80286 มันถูกเรียกว่าเป็นตัวเลือกและฉันไม่คิดว่าพวกเขาจะเปลี่ยนคำศัพท์อย่างเป็นทางการตั้งแต่นั้น
CVn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.