2011-11-11 34 views
7

Điều gì xảy ra nếu quá trình B ghi (với một thông thường viết() syscall) một số dữ liệu vào hình ảnh của quá trình A trong khi sau này đang thực hiện? Nó sẽ không gây ra tham nhũng của những gì quá trình A đang thực hiện?Viết để thực hiện quá trình 'hình ảnh trên Linux

Tôi mới sử dụng Linux. Theo tôi hiểu, Unix lịch sử không áp đặt các khóa tập tin bắt buộc (như Windows). Vì vậy, viết là hoàn toàn có thể.

Tôi đã tìm kiếm trên web mà không có kết quả. Khi tôi hỏi câu hỏi này, các đồng nghiệp có kinh nghiệm Linux của tôi, tất cả họ đều trả lời rằng quy trình A có hình ảnh hoàn toàn trong bộ nhớ của nó.

Tuy nhiên, từ những gì tôi đã đọc, hạt nhân có thể dễ dàng trao đổi một số trang trở lại tệp hình ảnh từ bộ nhớ, chẳng hạn như khi điều kiện bộ nhớ thấp bị nhấn mạnh. Vì vậy, trong khi trên đĩa, một số trang có thể có khả năng bị hỏng bởi một quá trình nhà văn khác; sau đó, chúng có thể được hoán đổi lại thành RAM và được thực thi.

+0

Kiểm tra trước đó: http://stackoverflow.com/questions/4453781/what-happens-when-you-overwrite-a-memory-mapped-executable – Antoine

Trả lời

2

Bạn đang nghĩ đến quá trình viết vào một số /proc/1234/mem của một quy trình khác là pid_t 1234?

Hoặc bạn đang nghĩ đến một quy trình viết vào thực thi ELF của một quy trình khác?

Cả hai scenarii đều không phổ biến và Linux cụ thể (khác Posix không có những), vì vậy tôi không biết điều gì có thể xảy ra trong trường hợp đó. Nhưng ít nhất là máy móc cho phép nên bảo vệ một số.

Xem thêm lỗi ETXTBSY.

Trên thực tế (như thể hiện bởi strace -f /usr/bin/gcc hello.c -o hello) trình biên dịch và mối liên kết được loại bỏ các thực thi trước khi open -ing nó cho văn bản thực thi, vì vậy hầu hết biên soạn bao giờ viết vào một tập tin thực thi cũ:

870 stat("hello", {st_mode=S_IFREG|0755, st_size=6096, ...}) = 0 
870 unlink("hello")     = 0 
870 open("hello", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0777) = 17 
870 fstat(17, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 

Vì vậy, để viết vào một tập tin thực thi, bạn phải cố gắng hết sức. Tất nhiên, khi bạn làm điều đó, tai nạn nghịch ngợm có thể xảy ra.

+0

tôi có nghĩa là kịch bản thứ hai. –

+0

ETXTBSY có khả năng là đầu mối lớn nhất ở đây, theo kinh nghiệm của tôi, bạn sẽ nhận được một lỗi của ETXTBSY nếu bạn đang cố gắng ghi đè lên các phần của một thực thi đang chạy.Và lưu ý rằng ghi đè nội dung của tệp là rất khác với việc xóa tệp và tạo tệp mới có cùng tên tệp trên hệ thống posix. – nos

+0

Câu hỏi được Antoine liên kết có các cuộc thảo luận chi tiết. Tôi nghĩ rằng ETXTBSY không xảy ra nhiều nữa (ngoại trừ các tập tin thực thi liên kết tĩnh). –

1

Bạn đã đọc gì cho thấy các trang có thể được đổi lại "thành tệp hình ảnh"?

Nếu hệ thống ở mức thấp trên bộ nhớ, các trang sẽ được đổi chỗ cho phân vùng trao đổi trên đĩa, khác với tệp thực thi. Việc ghi vào tệp thi hành sẽ không có hiệu lực cho đến khi bạn chạy tệp tiếp theo.

Nếu, bằng cách nào đó bạn có thể ghi vào trang chính xác trên tệp hoán đổi (điều này sẽ rất khó, vì bạn sẽ phải biết chính xác vị trí và thời điểm dữ liệu được ghi vào đĩa). Nếu bạn đã làm điều đó bạn có thể sửa đổi mã đối tượng. Bạn đang đề nghị làm hỏng tệp thực thi, hoặc một số cách thông minh để thay đổi một chương trình trong khi nó đang chạy?

+0

Tôi quan tâm đến khả năng không mong muốn của tham nhũng mã đối tượng. Tôi có nghi ngờ rằng hạt nhân sử dụng phân vùng trao đổi cho các hình ảnh thực thi; nó sẽ là quá lãng phí, theo như tôi có thể nghĩ về nó. Các hạt nhân thay vì bản đồ hình ảnh trong một thời trang tương tự như mmap bình thường. –

+0

Trang sạch sẽ không bị hoán đổi chút nào - chúng chỉ đơn giản là bị bỏ, được tải lại từ tệp mà chúng được ánh xạ từ nếu chúng cần lại. – caf

1

Trên thực tế, không cần thiết phải có "điều kiện bộ nhớ thấp" cho các trang được hoán đổi. Linux tải các tập tin thực thi "theo yêu cầu" anyway, do đó, một trang chỉ được tải khi nó được yêu cầu.

Nhưng xem câu trả lời của tôi vào một What happens when you overwrite a memory-mapped executable?

Các vấn đề liên quan