В чём разница между башом и программированием?
Dec 14 12:00:59 ubuntu dhclient[674]: Sending on Socket/fallback
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPDISCOVER on ens3 to 255.255.255.255 port 67 interval 3 (xid=0x2ad36074)
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPOFFER of 10.33.178.10 from 10.33.178.2
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPREQUEST for 10.33.178.10 on ens3 to 255.255.255.255 port 67 (xid=0x7460d32a)
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPACK of 10.33.178.10 from 10.33.178.2 (xid=0x2ad36074)
Dec 14 12:00:59 ubuntu audit[679]: AVC apparmor="DENIED" operation="exec" profile="/{,usr/}sbin/dhclient" name="/usr/bin/true" pid=679 comm="isc-worker0000" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
Да-да. Была вот такая строчка:
md5sum "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" > "$oldstate" 2> /dev/null || true
В которой автор кода сказал "да, пожалуйста, игнорируйте любые ошибки в этом месте", но пришёл apparmor и сказал "нельзя, нельзя". И случилось чудное.
Программисты шутят про #define TRUE FALSE, а сисамдины отлаживают.
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPDISCOVER on ens3 to 255.255.255.255 port 67 interval 3 (xid=0x2ad36074)
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPOFFER of 10.33.178.10 from 10.33.178.2
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPREQUEST for 10.33.178.10 on ens3 to 255.255.255.255 port 67 (xid=0x7460d32a)
Dec 14 12:00:59 ubuntu dhclient[674]: DHCPACK of 10.33.178.10 from 10.33.178.2 (xid=0x2ad36074)
Dec 14 12:00:59 ubuntu audit[679]: AVC apparmor="DENIED" operation="exec" profile="/{,usr/}sbin/dhclient" name="/usr/bin/true" pid=679 comm="isc-worker0000" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
Да-да. Была вот такая строчка:
md5sum "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" > "$oldstate" 2> /dev/null || true
В которой автор кода сказал "да, пожалуйста, игнорируйте любые ошибки в этом месте", но пришёл apparmor и сказал "нельзя, нельзя". И случилось чудное.
Программисты шутят про #define TRUE FALSE, а сисамдины отлаживают.
no subject
А вот если бы в башу написать
|| :, то злобный apparmor бы ничего не заметил.no subject
Помочь им нельзя.
no subject
no subject
Автор полиси неправ. Иметь исполняемый и работающий
true— конституционное право каждого шелл-скрипта, гарантируемое спецификацией POSIX.no subject
no subject
В спеке на семейство функций
execl,execle,execlp,execv,execve,execvp,fexecveперечислены условия, при которых вызов обязан вернуть код ошибкиEACCES, но формулировка такова, что этот список не исчерпывающий (“shall fail if”, не “if and only if”). Поэтому ты можешь иметь файл, иметь право execute на его родительский каталог и всех предков, ноexec*всё равно имеет право вернутьEACCES.А вот в спеке на
trueникаких условий не прописано. Обязано быть, обязано вернуть нулевой код возврата, обязано никак не трогать стандартный ввод-вывод.no subject
no subject
Так а я и говорю, что виноват автор полиси, которая сломала возможность запускать essential утилиту POSIX- окружения.
Ломать
exec*чего попало в целях повышения безопасности — можно. Ломатьexec*для конкретно/bin/true— нельзя.no subject
no subject
Если ставить вопрос в конструктивном ключе (кто будет исправлять код), то из прагматичных же соображений это будет "интегратор", т.е. тот кто пытается все эти четыре компонента собрать воедино. Если смотреть чуть глубже, то "по справедливости" это должен быть автор полиси, т.к. он нарушает сложившийся до него консенсус.
Рекурсивно углубляясь далее, мы неизбежно придём к вопросу "как дизайнить системы так, чтобы минимизировать подобные эксцессы" и на этот вопрос по-моему ни у кого нет хорошего ответа.
no subject
На самом деле, забыв про ужасы apparmor'а мы можем легко увидеть последствия этой связи в случае исчезновения корневой файловой системы (что легко может произойти, если вынуть системный диск). Языки программирования, в которых константы внутри языка не привязаны к существованию файлов (и файловой системы) продолжат работать, языки, в которых конструкции языка программирования намертво завязаны на файлую систему перестанут. (Я в курсе про файловый кеш в момент отвала файловой системы, но он не всегда доступен для конкретного файла и на это нельзя полагаться).
Ошибка тут, как мне кажется, именно в этом. Доступность файловой системы предположена абсолютная, что напоминает требования к надёжности у старых кобольных программ - выдайте нам идеально работающий сервер с 100% аптайма и без единой ошибки когда либо (все ошибки пускай мейнфреймы устраняют за счёт аппаратной избыточности).
Более того, в баше не предусмотрено никаких аварийных процедур на этот случай.
no subject
Именно в баше (и
dash’е) и именно дляtrueпредусмотрено:хотя, скорее всего, по производительностным соображениям, а не отказоустойчивостным. (А шелл-скрипт из корневого поста работает не в баше, а в каком-то другом shell’е.)
Также в принципе можно представить себе дистрибутив, который при загрузке создаёт RAM-диск и всё essential окружение живёт на нём, и в разумных пределах пофиг, что там отвалится или форс-размонтируется в процессе работы. Кажется, некоторые инсталляторы GNU/Linux’а так делают.
Доводилось мне видеть последствия отвала диска, на котором размещён своп. Байтораздирающее. Всё просто встаёт колом.
no subject