Czy PID procesu potomnego jest zawsze większy niż PID jego rodzica w systemie Linux?

22

Powiedzmy, że od jądra 2.6.

Obserwuję wszystkie uruchomione procesy w systemie.

Czy PID dzieci jest zawsze większy niż PID rodziców?

Czy możliwe są specjalne przypadki „inwersji”?

Massimo
źródło

Odpowiedzi:

47

Nie, z bardzo prostego powodu, że istnieje maksymalna wartość liczbowa, jaką może mieć PID. Jeśli proces ma najwyższy PID, żadne dziecko podrzędne nie może mieć większego PID. Alternatywą dla zapewnienia dziecku niższego PID byłoby fork()całkowite niepowodzenie , co nie byłoby zbyt produktywne.

Identyfikatory PID są przydzielane w kolejności, a po użyciu najwyższego, system owija się w celu ponownego wykorzystania (bezpłatnych) niższych, dzięki czemu można uzyskać niższe PID dla dziecka również w innych przypadkach.

Domyślny maksymalny PID w moim systemie ( /proc/sys/kernel/pid_max) to tylko 32768, więc nie jest trudno osiągnąć warunek, w którym następuje obejście.

$ echo $$
27468
$ bash -c 'echo $$'
1296
$ bash -c 'echo $$'
1297

Gdyby twój system przydzielał PID losowo ( jak wydaje się to robić OpenBSD ) zamiast kolejno (jak Linux), byłyby dwie opcje. Albo losowy wybór został dokonany na całej przestrzeni możliwych PID, w którym to przypadku byłoby oczywiste, że PID dziecka może być niższy niż rodzic. Lub też PID dziecka byłby wybierany losowo z wartości większych niż PID rodzica, co średnio umieszczałoby go w połowie między PID rodzica a maksimum. Procesy rozwidlania rekurencyjnie szybko osiągnęłyby maksimum i bylibyśmy w tym samym punkcie, co wspomniano powyżej: nowy widelec musiałby użyć niższego PID, aby odnieść sukces.

ilkkachu
źródło
3
FWIW, istnieją systemy, w których PID są przydzielane losowo (domyślnie na przykład w OpenBSD), i jestem pewien, że widziałem podobny schemat alokacji PID również w Linuksie (lub przynajmniej jeden sugerowany).
Kusalananda
@Kusalananda, tak, myślę, że było również pytanie na ten temat na unix.SE. Nie mam czasu go wykopać, ale o ile pamiętam, łatka dla Linuksa, która losowo wybierała PID, była stara i porzucona jako niepotrzebna. Nie ma to jednak znaczenia: o ile istnieje (względnie niski) maksymalny PID, po jego użyciu można wybrać albo niższy PID, albo upuścić błąd na rozwidleniu.
ilkkachu
2
@Massimo, aspekt bezpieczeństwa jest omawiany w tym pytaniu na security.se: Czy randomizowane PID zapewniają większe bezpieczeństwo?
ilkkachu
1
@RonJohn, cóż, nie wiem, jakie są wartości innych Linuksów, ale można to modyfikować, możesz ustawić go na około 4 miliony (4194304 lub 2 ^ 22) w systemach 64-bitowych. (to liczba, a nie ilość bajtów)
ilkkachu
8

Istnieje również możliwość wystąpienia luk w zabezpieczeniach przy użyciu powiadomień jądra i rozwidlania się, aby uniknąć wykrycia przez skanowanie tabeli procesów; jeśli zostanie to właściwie wykonane, proces ma niższy PID, a narzędzia procesu nie widzą danego procesu.

http://cve.circl.lu/cve/CVE-2018-1121

procps-ng, procps jest podatny na proces ukryty w warunkach rasowych. Ponieważ proc_pid_readdir () jądra zwraca wpisy PID w rosnącej kolejności numerycznej, proces zajmujący wysoki PID może wykorzystywać zdarzenia inotify w celu ustalenia, kiedy skanowana jest lista procesów, i rozwidlać / exec, aby uzyskać niższy PID, unikając w ten sposób wyliczenia. Nieuprzywilejowany atakujący może ukryć proces przed narzędziami procps-ng, wykorzystując warunek wyścigu podczas odczytywania wpisów / proc / PID. Luka ta dotyczy procps i procps-ng do wersji 3.3.15, może to również dotyczyć nowszych wersji.

gałązka
źródło