Я тут зробив те, щоб перевірити, чи корень init
процесу (PID 1) такий, як корінь поточного процесу. Хоча /proc/1/root
це завжди посилання на /
(якщо тільки init
не вказано, але це мене не хвилює), наступне воно веде до "головного" кореневого каталогу. Ця методика використовується в кількох сценаріях технічного обслуговування в Debian, наприклад, для пропуску початкового udev після встановлення в chroot.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(До речі, це ще один приклад того, чому chroot
він марний для безпеки, якщо до хронізованого процесу є кореневий доступ. Некореневі процеси не можуть читати /proc/1/root
, але вони можуть слідувати, /proc/1234/root
якщо є запущений процес з PID 1234, який працює як той самий користувач.)
Якщо у вас немає прав суперкористувача, ви можете подивитися на /proc/1/mountinfo
і /proc/$$/mountinfo
(коротко описані в filesystems/proc.txt
в документації ядра Linux ). Цей файл читається у всьому світі та містить багато інформації про кожну точку монтажу в режимі подання файлової системи. Шлях у цьому файлі обмежується chroot, що впливає на читацький процес, якщо такий є. Якщо зчитування процесу /proc/1/mountinfo
хроноване у файлову систему, що відрізняється від глобального кореня (якщо припустимо, що корінь pid 1 є глобальним коренем), то в ньому не /
відображається жодна запис /proc/1/mountinfo
. Якщо читання процесу /proc/1/mountinfo
є ізольованим в каталог на глобальній кореневої файлової системи, то запис для /
з'являюся в /proc/1/mountinfo
, але з іншим ідентифікатором монтування. До речі, кореневе поле ($4
) вказує, де chroot знаходиться в його головній файловій системі.
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
Це чисте рішення для Linux. Це може бути узагальнювальним для інших варіантів Unix з досить схожим /proc
(у Solaris є подібний /proc/1/root
, я думаю, але ні mountinfo
).