Tạo một quy trình không thành công trên Linux


14

Tôi đang làm việc trên một ứng dụng quản lý mật khẩu và vì lý do bảo mật, tôi muốn khởi chạy một quy trình không thể thực hiện được.

Và ngoài ra tôi không muốn chương trình này trở thành một daemon vì tôi cần đọc từ đầu vào tiêu chuẩn và viết cho nó.

Có cách nào để làm việc này không?


11
"vì lý do bảo mật, tôi muốn khởi chạy một quy trình không thể thực hiện được." Chỉ cần một lưu ý - nếu điều này được cho phép, mọi người có thể dễ dàng khai thác nó vì những lý do bất chính - ví dụ, phóng một quả bom nĩa không thể ngăn chặn.
VLAZ

32
Điều này nghe có vẻ như là một vấn đề XY . Tôi nghi ngờ rằng bất cứ điều gì bạn đang thực sự cố gắng để đạt được, một quá trình không thành công không phải là cách để làm điều đó. "Vì lý do bảo mật" là rất mơ hồ. Chính xác thì bạn muốn ngăn người dùng làm gì? Họ có quyền truy cập gì?
Nate Eldredge

4
Bất kỳ quá trình nào không thể thực hiện được cho tất cả ý định và mục đích là vi-rút.
Naftuli Kay

3
@NateEldredge: Thay vào đó, hãy để chương trình bỏ qua các tín hiệu. Đó là cách điển hình để làm điều đó; nếu không, ai đó có thể gửi SIGINT hoặc SIGTSTP trực tiếp đến quy trình, bỏ qua thiết bị đầu cuối.
Noah Spurrier

2
@NoahSpurrier: Tôi đang tưởng tượng một tình huống trong đó bạn có một người dùng có thể nhập mọi thứ trên bảng điều khiển, nhưng người khác không thể thực thi mã trên máy tính (như kiosk). Bạn thiết lập nó để không có khóa nào họ có thể gõ sẽ có tác dụng không mong muốn. Nếu họ có thể thực thi mã khác, thì bỏ qua SIGINT và SIGTSTP và SIGQUIT không giúp ích gì; bất cứ ai có thể gửi những tín hiệu đó trực tiếp đến quá trình cũng có thể gửi SIGKILL hoặc SIGSTOP mà bạn không thể bỏ qua.
Nate Eldredge

Câu trả lời:


41

Tận dụng chạy quản lý mật khẩu theo một người dùng riêng biệt và xử lý / ignore / khối thiết bị đầu cuối tạo tín hiệu ( SIGINT, SIGQUIT, SIGHUP, SIGTSTP, SIGTTIN, và SIGTTOU).

Bạn không thể gửi tín hiệu đến (= kill) các quy trình chạy dưới một người dùng khác (người dùng có cả uid thực và uid được lưu khác với uid hiệu quả của bạn) trừ khi id hiệu quả của bạn là 0 (root).

Tất cả các quy trình sẽ vẫn có thể bị giết bởi root.

Để biết thêm chi tiết, xem kill (2) .


15

Cách duy nhất để làm cho một quá trình không thành công là thực hiện nó như một luồng nhân , đây không phải là một việc nhỏ.

Bạn vẫn có thể giết nó nhưng đó sẽ là một thiệt hại tài sản thế chấp hệ điều hành.

Bạn cũng có thể phát triển một mô-đun hạt nhân tùy chỉnh sẽ đặt SIGNAL_UNKILLABLEcờ cho quy trình của bạn. Cờ này được thiết kế để chỉ được đặt cho init(hoặc systemd, bất kỳ quy trình ban đầu nào khởi chạy kernel), là quy trình người dùng duy nhất được bảo vệ chống lại sự giết chết vô điều kiện nhưng dường như không có gì cấm cờ đó có mặt cho một quy trình thông thường.


1
nó có thể là quá trình init
muhmuhten

@muhmuhten Bạn nói đúng, init là một quá trình sử dụng được bảo vệ chống lại sự giết chóc vô điều kiện. Tuy nhiên, nó không được thiết kế để được tùy chỉnh trong khi chắc chắn có API cho các mô-đun và luồng nhân.
jlliagre

Để giải thích cho câu trả lời của riêng tôi, tôi giả sử rằng bạn không có quyền truy cập vào tài khoản root (tình cờ, gợi ý đây là ví dụ về đồ chơi, dự án khóa học hoặc phần mềm độc hại). Loại trừ ý tưởng rằng bạn có thể nối một mô-đun hạt nhân cho mục đích đó. Cũng lưu ý rằng cờ SIGNAL_UNKILLABLE không khả dụng cho các quy trình thông thường và loại trừ một số hoạt động bình thường quan trọng (như vforking) và vì vậy tôi sẽ coi đó là trường hợp cạnh thông thường không thực tế.
GregD

@jlliagre thực sự, nó không phải là.
muhmuhten

@dudek Một quy trình không thành công đã là một trường hợp cạnh thường không thực tế.
jlliagre

11

Về mặt kỹ thuật, không có cách nào để làm cho một quá trình không thành công.

Tất nhiên, đối với người dùng không phải root, họ chỉ có thể giết các tiến trình có cùng ID người dùng mà họ làm, vì vậy nếu bạn có thể tạo các tài khoản khác nhau, bạn có thể sử dụng ID người dùng "duy nhất" cho quy trình và sau đó chỉ root mới có thể giết được.

Một giải pháp đơn giản nhưng ít mạnh mẽ hơn là để quá trình của bạn bắt được càng nhiều tín hiệu càng tốt (có thể bỏ qua chúng). Điều này chỉ phù hợp với các ví dụ về đồ chơi hoặc môi trường không đối nghịch vì không có cách nào bắt được tín hiệu KILL (tín hiệu 9), nhưng nếu không, bạn có thể tránh bị giết bởi chúng.

Cuối cùng, bạn có thể sắp xếp để hồi sinh quá trình nếu bị giết. Điều này cũng dễ vỡ (rất mong manh), nhưng sẽ làm cho nó khó khăn hơn một chút để thoát ra. Điều này có thể được thực hiện bằng cách sử dụng quy trình giám sát của riêng bạn hoặc sử dụng inittab. Đối với một kẻ thù biết những gì họ đang làm, điều này có thể dễ dàng phá vỡ bằng cách giết chết nhiều quá trình cùng một lúc.


1
Nhưng (ngoài inittab) có thể quá trình giám sát cũng có thể bị giết, phải không?
roaima

Không, trình điều khiển thiết bị (mô-đun hạt nhân) có thể tạo các quy trình không thể bị giết bởi root.
Noah Spurrier
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.