Không cho phép chương trình chế độ người dùng truy cập bộ nhớ không gian kernel và thực thi các lệnh IN và OUT đánh bại mục đích có các chế độ CPU?


19

Khi CPU ở chế độ người dùng, CPU không thể thực hiện các hướng dẫn đặc quyền và không thể truy cập bộ nhớ không gian kernel.

Và khi CPU ở chế độ kernel, CPU có thể thực hiện tất cả các hướng dẫn và có thể truy cập tất cả bộ nhớ.

Bây giờ trong Linux, một chương trình chế độ người dùng có thể truy cập tất cả bộ nhớ (sử dụng /dev/mem) và có thể thực thi hai hướng dẫn đặc quyền INOUT(sử dụng iopl()tôi nghĩ).

Vì vậy, một chương trình chế độ người dùng trong Linux có thể thực hiện hầu hết mọi thứ (tôi nghĩ rằng hầu hết mọi thứ) có thể được thực hiện trong chế độ kernel.

Không cho phép chương trình chế độ người dùng có tất cả sức mạnh này đánh bại mục đích có chế độ CPU?

Câu trả lời:


23

Vì vậy, một chương trình chế độ người dùng trong Linux có thể thực hiện hầu hết mọi thứ (tôi nghĩ rằng hầu hết mọi thứ) có thể được thực hiện trong chế độ kernel.

Chà, không phải tất cả các chương trình chế độ người dùng đều có thể, chỉ những chương trình có đặc quyền phù hợp. Và điều đó được xác định bởi kernel.

/dev/memđược bảo vệ bởi các quyền truy cập hệ thống tập tin thông thường và CAP_SYS_RAWIOkhả năng. iopl()ioperm()cũng bị hạn chế thông qua khả năng tương tự.

/dev/memcũng có thể được biên dịch ra khỏi kernel hoàn toàn ( CONFIG_DEVMEM).

Không cho phép chương trình chế độ người dùng có tất cả sức mạnh này đánh bại mục đích có chế độ CPU?

Vâng, có lẽ. Nó phụ thuộc vào những gì bạn muốn các quy trình không gian người dùng đặc quyền có thể làm. Các quy trình không gian người dùng cũng có thể rác toàn bộ ổ đĩa cứng nếu chúng có quyền truy cập /dev/sda(hoặc tương đương), mặc dù điều đó đánh bại mục đích có trình điều khiển hệ thống tệp để xử lý truy cập lưu trữ.

(Sau đó, có một thực tế là iopl()hoạt động bằng cách sử dụng các chế độ đặc quyền CPU trên i386, do đó không thể nói là đánh bại mục đích của chúng.)


2
Thậm chí ioplkhông cho phép tất cả các hướng dẫn đặc quyền, vì vậy nó vẫn hữu ích để đảm bảo chương trình không gian người dùng bị lỗi không vô tình chạy invdbằng cách nhảy qua một con trỏ hàm bị hỏng chỉ vào bộ nhớ thực thi bắt đầu bằng 0F 08byte. Tôi đã thêm một câu trả lời với một số lý do không bảo mật tại sao việc xử lý không gian người dùng nâng cao đặc quyền của họ là hữu ích.
Peter Cordes

16

Chỉ trong cùng một cách modprobe"đánh bại" bảo mật bằng cách tải mã mới vào kernel.

Vì nhiều lý do, đôi khi có ý nghĩa hơn khi có mã bán đặc quyền (như trình điều khiển đồ họa bên trong máy chủ X) chạy trong không gian người dùng thay vì luồng nhân.

  • Có thể killdễ dàng hơn, trừ khi nó khóa CTNH.
  • Có yêu cầu trang mã / dữ liệu của nó từ các tệp trong hệ thống tệp. (Bộ nhớ kernel không thể phân trang)
  • Cung cấp cho nó không gian địa chỉ ảo của riêng nó, nơi các lỗi trong máy chủ X có thể làm sập máy chủ X mà không lấy kernel.

Nó không làm được gì nhiều cho bảo mật, nhưng có những lợi thế lớn về độ tin cậy và kiến ​​trúc phần mềm.

Trình điều khiển đồ họa nướng vào kernel có thể làm giảm chuyển đổi ngữ cảnh giữa máy khách X và máy chủ X, giống như chỉ một người dùng-> kernel-> người dùng thay vì phải đưa dữ liệu vào một quy trình sử dụng không gian khác, nhưng về mặt lịch sử, máy chủ X quá lớn và quá lỗi muốn chúng đầy đủ trong kernel.


Có, mã độc với những quyền riêng tư này có thể chiếm quyền hạt nhân nếu nó muốn, sử dụng /dev/memđể sửa đổi mã hạt nhân.

Hoặc trên x86 chẳng hạn, hãy chạy một clilệnh để vô hiệu hóa các ngắt trên lõi đó sau khi thực hiện một ioplcuộc gọi hệ thống để đặt mức đặc quyền IO của nó thành chuông 0.

Nhưng ngay cả x86 iopl"chỉ" cung cấp quyền truy cập vào một số hướng dẫn : vào / ra (và các phiên bản chuỗi in / outs) và cli / sti. Nó không cho phép bạn sử dụng rdmsrhoặc wrmsrđọc hoặc ghi "các thanh ghi cụ thể của mô hình" (ví dụ: IA32_LSTARđặt địa chỉ điểm nhập hạt nhân cho lệnh x86-64 syscall) hoặc sử dụng lidtđể thay thế bảng mô tả ngắt (sẽ cho phép bạn hoàn toàn lấy qua máy từ kernel hiện có, ít nhất là trên lõi đó.)

Bạn thậm chí không thể đọc các thanh ghi điều khiển (như CR3 chứa địa chỉ vật lý của thư mục trang cấp cao nhất, một quá trình tấn công có thể hữu ích như một sự bù đắp /dev/memđể sửa đổi các bảng trang của chính nó như là một thay thế cho mmapnhiều hơn /dev/mem. )

invd(làm mất hiệu lực tất cả các bộ nhớ cache mà không cần ghi lại !! ( trường hợp sử dụng = BIOS sớm trước khi RAM được cấu hình)) là một điều thú vị khác luôn yêu cầu CPL 0 đầy đủ (mức đặc quyền hiện tại), không chỉ IOPL. Thậm chí wbinvdlà đặc quyền bởi vì nó rất chậm (và không bị gián đoạn), và phải xóa tất cả các bộ nhớ cache trên tất cả các lõi. (Xem Có cách nào để xóa toàn bộ bộ đệm CPU liên quan đến chương trình không?cách sử dụng lệnh WBINVD )

Lỗi dẫn đến việc nhảy đến một địa chỉ xấu đang chạy dữ liệu dưới dạng mã do đó không thể thực hiện bất kỳ hướng dẫn nào trong số các hướng dẫn này trong máy chủ X không gian người dùng.


Mức đặc quyền hiện tại (ở chế độ dài và được bảo vệ) là 2 bit thấp của cs(bộ chọn phân đoạn mã) . mov eax, cs/ and eax, 3hoạt động ở bất kỳ chế độ nào để đọc cấp đặc quyền.

Để viết cấp đặc quyền, bạn thực hiện jmp farhoặc call farđặt CS:RIP(nhưng mục nhập GDT / LDT cho phân khúc mục tiêu có thể hạn chế cấp dựa trên cấp đặc quyền cũ, đó là lý do tại sao không gian người dùng không thể làm điều này để tự nâng cao). Hoặc bạn sử dụng inthoặc syscallđể chuyển sang vòng 0 tại điểm nhập kernel.


Trên thực tế, tôi khá chắc chắn rằng đó chỉ là mã "bộ chọn" trong parlace của Intel. Đó là một phân khúc trong 8086/8088, có thể là vào năm 80186, nhưng đến năm 80286, nó được gọi là một bộ chọn và tôi không nghĩ rằng họ đã chính thức thay đổi thuật ngữ đó kể từ đó.
một CVn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.