Liệu linux có biện pháp nào để bảo vệ chống bom ngã ba không?


12
#include <unistd.h>
int main(int argc, char* argv[]) {
  while(1)
  {
    fork();
  } 
}

Tôi chạy chương trình này trên linux của tôi, không có gì xuất ra trên thiết bị đầu cuối, hệ điều hành dường như đã chết. Liệu linux có biện pháp bảo vệ nào cho chương trình đó có thể hết bộ nhớ không?


2
Tôi nghi ngờ tác động sẽ ít hơn rất nhiều nếu bạn không làm theo lời khuyên tồi tệ mà nhiều nhà phân phối đưa ra để tạo phân vùng trao đổi lớn ...
R ..

1
Có phải "không tạo ra bất kỳ quy trình mới nào sau khi đạt 65k" được tính là biện pháp đối phó không? ;)
Bobby

Câu trả lời:


18

Điều này được gọi là một quả bom ngã ba .

Liệu linux có biện pháp bảo vệ nào cho chương trình đó có thể hết bộ nhớ không?

Không hẳn vậy. Mỗi ngã ba tạo ra một quy trình mới, với không gian địa chỉ ảo và sử dụng bộ nhớ riêng. Vì vậy, mỗi bản sao tương đối nhỏ. Cuối cùng, bạn sẽ sử dụng hết bộ nhớ vật lý + trao đổi trên hệ thống và kẻ giết người hết bộ nhớ (OOM) sẽ bắt đầu giết chết các quy trình riêng lẻ. Nhưng bom ngã ba vẫn sẽ tạo ra các quy trình nhanh như vậy (nếu không nhanh hơn).

Một cách để ngăn chặn điều này xảy ra ở nơi đầu tiên là hạn chế số lượng quy trình người dùng, sử dụng ulimit -u(giả sử bạn đang sử dụng Bash; các shell khác sẽ có tương đương).


2
Một điều cần lưu ý ulimitlà cụ thể đối với bash; các shell khác có thể sẽ có cùng một lệnh tích hợp, nhưng có thể với một tên khác.
Jay

@Jay: Điểm công bằng. Tôi đã lưu ý rằng trong câu trả lời bây giờ, cảm ơn!
Oliver Charlesworth

1
giới hạn bộ nhớ / mô tả tập tin cho mỗi người dùng là đủ. Giới hạn bộ nhớ cho mỗi người dùng luôn là một ý tưởng tốt. Khi một tiến trình bị giết (oom), cơ quan giám sát sẽ gửi thông báo để BOFH có thể khởi động 'người dùng lừa đảo' với tất cả các quy trình thuộc hệ thống

Tôi tin rằng bạn cũng có thể đặt một số giới hạn thông qua các tham số đăng nhập
p_l

10

Có, mặc dù nó có thể không được bật theo mặc định trên hệ thống của bạn. Cuộc setrlimitgọi hệ thống xác định giới hạn hệ thống - bao gồm số lượng quy trình cho mỗi người dùng.

Trước tiên hãy xem xét nó trong API kernel (vì bạn đã đề cập đến "linux"): bạn có thể sử dụng manpage cho setrlimit, điều này sẽ cho bạn biết làm gì đó như

#include <sys/resource.h>
...

struct rlimit  r;

rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);

Điều này sẽ đặt các quy trình tối đa cho mỗi người dùng ( RLIMIT_NPROC) thành 40 (giới hạn mềm) và 50 (giới hạn cứng).

Bây giờ, từ shell, nếu bạn sử dụng bash, bạn có thể sử dụng ulimitlệnh tích hợp:

ulimit -u
29089

Bạn có thể đặt giới hạn bằng cách chuyển nó làm đối số:

ulimit -u 100

ulimit --help sẽ cho bạn thấy rằng có một số giới hạn khác mà bạn có thể đặt (một giới hạn có thể quan tâm là số lượng mô tả tệp tối đa được người dùng sử dụng).


7

Nó phụ thuộc nếu bạn muốn sử dụng nó ở cấp độ người dùng hoặc cấp độ hệ thống. Ở cấp độ người dùng, ulimit(hoặc các lệnh tương ứng cho các shell khác) sẽ là giải pháp dễ nhất.

Tuy nhiên, ở cấp độ hệ thống, có các cơ chế để ngăn chặn người dùng độc hại (hoặc không sử dụng ulimit) dừng hệ thống. Cơ chế cgroups Linux có thể giới hạn tài nguyên trên cơ sở từng nhóm. Bạn có thể buộc (bằng máy móc pam_systemd) phiên người dùng nằm trong nhóm cụ thể. Điều này có lợi ích khác, ví dụ, bộ lập lịch CPU.


1
+1: các nhóm thực sự mới và hầu hết mọi người chưa biết nhiều về họ. Chúng ta có thể tìm hiểu thêm ở đâu?
Ken Bloom

1
@KenBloom: 1. bằng cách duyệt /sys/fs/cgroup/2. bằng cách tìm kiếm trong google 3. bằng cách duyệt qua make menuconfig4. Bằng cách xem qua /usr/src/linux/Documentation/cgroups5. Bằng cách đọc tài liệu systemd. Xin lỗi tôi không thể giúp nhiều hơn nhưng tôi chỉ sử dụng những tài nguyên đó. Tôi đã sử dụng các nhóm trên máy tính để bàn để kiểm soát tài nguyên.
Maciej Piechotka

6

Sử dụng ulimit -utừ bash shell để đặt giới hạn cho "quy trình người dùng tối đa".

Từ trình bao C, bạn sử dụng limitlệnh.

Nếu bạn cần một cuộc gọi hệ thống để thực hiện việc này, hãy sử dụng setrlimitcuộc gọi để đặt RLIMIT_NPROC.


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.