<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>23058</bug_id>
          
          <creation_ts>2010-03-03 11:40:51 +0300</creation_ts>
          <short_desc>Создаётся нерабочий initrd если $TMPDIR смонтирован c noexec</short_desc>
          <delta_ts>2013-04-27 17:32:29 +0400</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>4</classification_id>
          <classification>Development</classification>
          <product>Sisyphus</product>
          <component>make-initrd</component>
          <version>unstable</version>
          <rep_platform>all</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P3</priority>
          <bug_severity>minor</bug_severity>
          <target_milestone>---</target_milestone>
          
          <blocked>24406</blocked>
          <everconfirmed>1</everconfirmed>
          <reporter name="serpiph">serpiph</reporter>
          <assigned_to name="Alexey Gladkov">legion</assigned_to>
          <cc>antohami</cc>
    
    <cc>glebfm</cc>
    
    <cc>lav</cc>
    
    <cc>ldv</cc>
    
    <cc>legion</cc>
    
    <cc>mike</cc>
    
    <cc>placeholder</cc>
    
    <cc>vl_buharin</cc>
    
    <cc>vt</cc>
          
          <qa_contact>qa-sisyphus</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>107336</commentid>
    <comment_count>0</comment_count>
    <who name="serpiph">serpiph</who>
    <bug_when>2010-03-03 11:40:51 +0300</bug_when>
    <thetext>Второй раз натыкаюсь на грабли от make-initrd (при работе installkernel): создаётся нерабочий initrd для устанавливаемого ядра. Ядро выпадает в kernel panic с сообщением о невозможности найти init. Поиск проблемы показал, что в initrd файл /init лежит, но это скрипт и в нём указана программа /bin/sh, которой почему-то не оказалось в initrd. Полученный нерабочий initrd (2Мб) и рабочий от программы mkinitrd (1Мб) могу выслать лично по почте. Здесь прикреплять не буду. Ошибка повторяется, если удалить initrd и создать его через installkernel при установленном make-initrd.
$ rpm -qa|grep initrd
make-initrd-devmapper-0.2.2-alt1
mkinitrd-busybox-1.3.2-alt1
make-initrd-0.2.2-alt1
mkinitrd-initramfs-3.0.10-alt1
mkinitrd-3.0.10-alt1
make-initrd-lvm-0.2.2-alt1
$
Файловая система:
/dev/sda2 on / type xfs (rw)
proc on /proc type proc (rw,noexec,nosuid,gid=19)
sysfs on /sys type sysfs (rw)
udevfs on /dev type tmpfs (rw)
devpts on /dev/pts type devpts (rw)
shmfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext3 (ro,nosuid,nodev)
/dev/sda5 on /usr type xfs (rw)
/dev/sda6 on /var type xfs (rw)
/dev/sda9 on /home type xfs (rw)
jacktmp on /var/lib/jack/tmp type ramfs (rw)
tmpfs on /tmp type tmpfs (rw,noexec,nosuid,size=10%)
usbfs on /proc/bus/usb type usbfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107342</commentid>
    <comment_count>1</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-03 13:41:47 +0300</bug_when>
    <thetext>(В ответ на комментарий №0)
&gt; tmpfs on /tmp type tmpfs (rw,noexec,nosuid,size=10%)
                               ^^^^^^
Я думаю, что это может быть из-за noexec.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107344</commentid>
    <comment_count>2</comment_count>
    <who name="serpiph">serpiph</who>
    <bug_when>2010-03-03 14:06:30 +0300</bug_when>
    <thetext>(В ответ на комментарий №1)
&gt; (В ответ на комментарий №0)
&gt; &gt; tmpfs on /tmp type tmpfs (rw,noexec,nosuid,size=10%)
&gt;                                ^^^^^^
&gt; Я думаю, что это может быть из-за noexec.

Точно, перемонтировал /tmp с exec и в initrd появилась ссылка /bin/sh-&gt;/bin/ash. А ведь никакой ошибки на экран не выдавалось с noexec. Теперь непонятно, считать ли это всё равно ошибкой или закрыть по причине local misconfiguration?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107345</commentid>
    <comment_count>3</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-03 14:22:15 +0300</bug_when>
    <thetext>(В ответ на комментарий №2)
&gt; Точно, перемонтировал /tmp с exec и в initrd появилась ссылка
&gt; /bin/sh-&gt;/bin/ash. А ведь никакой ошибки на экран не выдавалось с noexec.
&gt; Теперь непонятно, считать ли это всё равно ошибкой или закрыть по причине local
&gt; misconfiguration?

Давайте понизим Важность и оставим открытой ... я попробую придумать что тут можно сделать.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107346</commentid>
    <comment_count>4</comment_count>
    <who name="Sir Raorn">raorn</who>
    <bug_when>2010-03-03 14:34:22 +0300</bug_when>
    <thetext>fakeroot может помочь?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107348</commentid>
    <comment_count>5</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-03 14:50:45 +0300</bug_when>
    <thetext>(В ответ на комментарий №4)
&gt; fakeroot может помочь?

Лёх, ты не понял. make-initrd и так уже рут (причём настоящий). В /tmp нельзя ничего исполнить.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107350</commentid>
    <comment_count>6</comment_count>
    <who name="serpiph">serpiph</who>
    <bug_when>2010-03-03 14:57:33 +0300</bug_when>
    <thetext>(В ответ на комментарий №3)

&gt; Давайте понизим Важность и оставим открытой ... я попробую придумать что тут
&gt; можно сделать.

Хорошо. Пусть хотя бы ошибку или предупреждение выдаёт, если где-то сборка initrd затыкается, а то сейчас в заблуждение вводит.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107366</commentid>
    <comment_count>7</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-04 01:29:22 +0300</bug_when>
    <thetext>Собственно понятно: код &quot;[ -x ./bin/$n ] || continue&quot; не отработал из-за noexec и продиагностировать это не представляется возможным без анализа опций монтирования раздела, на котором мы создаём временный каталог.

В качестве одного из путей решения это замена -x на -f, но это не правильно.

Думаю перенести сборку в ${TMPDIR:-/tmp} и склоняюсь, что подобные случаи это local misconfiguration т.к. программы имеют право создавать и исполнять скрипты во временном каталоге (где же им ещё это делать?).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107376</commentid>
    <comment_count>8</comment_count>
    <who name="Sir Raorn">raorn</who>
    <bug_when>2010-03-04 11:36:01 +0300</bug_when>
    <thetext>Сергей, вы таки попробуйте запустить make-initrd через fakeroot.  Оно же ещё и за правами на файлы следит, а не только &quot;кагбе рута&quot; даёт.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107378</commentid>
    <comment_count>9</comment_count>
    <who name="serpiph">serpiph</who>
    <bug_when>2010-03-04 14:10:59 +0300</bug_when>
    <thetext>Интересно, а почему mkinitrd не затыкается? Ведь задача этих программ - это сделать загрузочный образ для адра. Сам образ правильный создаётся (в том числе и права есть 755 на /bin/ash сотоварищи), а значит noexec в создании образа не помеха, единственно нет только симлинка /bin/sh -&gt; /bin/ash.

Хотя да, с noexec я переборщил. :-) У себя уже убрал.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107379</commentid>
    <comment_count>10</comment_count>
    <who name="Sir Raorn">raorn</who>
    <bug_when>2010-03-04 14:22:48 +0300</bug_when>
    <thetext>Инсталлер, кстати, прописывает только nosuid для /tmp.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107382</commentid>
    <comment_count>11</comment_count>
    <who name="serpiph">serpiph</who>
    <bug_when>2010-03-04 15:02:22 +0300</bug_when>
    <thetext>(В ответ на комментарий №10)
&gt; Инсталлер, кстати, прописывает только nosuid для /tmp.

У меня система стоит с тех пор, когда ещё это не прописывалось. :-) И я сам строчку на основе /dev смастерил, не подумав про noexec.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107384</commentid>
    <comment_count>12</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-04 15:31:47 +0300</bug_when>
    <thetext>(В ответ на комментарий №9)
&gt; Интересно, а почему mkinitrd не затыкается? Ведь задача этих программ - это
&gt; сделать загрузочный образ для адра. Сам образ правильный создаётся (в том числе
&gt; и права есть 755 на /bin/ash сотоварищи), а значит noexec в создании образа не
&gt; помеха, единственно нет только симлинка /bin/sh -&gt; /bin/ash.

Вы ошибаетесь. Вы не знаете как действует noexec. Вы можете скопировать выполняемый файл на такой раздел, но execute permission не будет действовать.
Вы не сможете выполнить такой файл и не сможете проверить файл на _исполняемость_.

mkinitrd только копировал файлы в директорию, не выполняя над ними других действий.

make-initrd после копирования файлов ищет шелл (т.к. он допускает копирования любого шелла) и если нужно делает симлинк /bin/sh. Он выполняет &quot;[ -x /somefile ]&quot; который всегда false с noexec. Поэтому симлинк не создаётся.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107412</commentid>
    <comment_count>13</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2010-03-04 22:28:13 +0300</bug_when>
    <thetext>(In reply to comment #7)
&gt; В качестве одного из путей решения это замена -x на -f, но это не правильно.
Думаю, хотеть исполняемый /tmp более неправильно.  А чуть ли не основной повод не делать его noexec из коробки -- mc. :-/

(In reply to comment #12)
&gt; make-initrd после копирования файлов ищет шелл (т.к. он допускает копирования
&gt; любого шелла) и если нужно делает симлинк /bin/sh. Он выполняет &quot;[ -x /somefile
&gt; ]&quot; который всегда false с noexec. Поэтому симлинк не создаётся.
Может, find /tmp/sh -perm +0111?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107419</commentid>
    <comment_count>14</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 00:34:32 +0300</bug_when>
    <thetext>(В ответ на комментарий №13)
&gt; Думаю, хотеть исполняемый /tmp более неправильно.  А чуть ли не основной повод
&gt; не делать его noexec из коробки -- mc. :-/

С первым утверждением в корне не согласен. И аргумент я уже называл: программы имеют право генерировать скрипты и исполнять их. Твоё решение ведёт к тому, что они будут это делать в неожиданных местах вместо законного TMPDIR.

Я не могу гарантировать, что в этом проекте не появятся скрипты выполняемые из workdir.

&gt; Может, find /tmp/sh -perm +0111?

Вот только не нужно придумывать хаки для замены стандартной проверки. &quot;test -x&quot; это совершенно легальная и правильная проверка.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107430</commentid>
    <comment_count>15</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 01:47:40 +0300</bug_when>
    <thetext>(In reply to comment #14)
&gt; (В ответ на комментарий №13)
&gt; &gt; Думаю, хотеть исполняемый /tmp более неправильно.  А чуть ли не основной повод
&gt; &gt; не делать его noexec из коробки -- mc. :-/
&gt; 
&gt; С первым утверждением в корне не согласен. И аргумент я уже называл: программы
&gt; имеют право генерировать скрипты и исполнять их.

Не все программы имеют такое право.  И, обрати внимание, именно твоя программа оказалась в той системе первой, кому это право понадобилось.  Зачем открывать этот ящик раньше времени?

&gt; Твоё решение ведёт к тому, что
&gt; они будут это делать в неожиданных местах вместо законного TMPDIR.

В неожиданных местах они будут неожиданно получать EROFS или EACCES.
Имей в виду наличие всяких ручек вроде selinux.

&gt; Я не могу гарантировать, что в этом проекте не появятся скрипты выполняемые из
&gt; workdir.

Почему ты не можешь этого гарантировать?

&gt; &gt; Может, find /tmp/sh -perm +0111?
&gt; 
&gt; Вот только не нужно придумывать хаки для замены стандартной проверки. &quot;test -x&quot;
&gt; это совершенно легальная и правильная проверка.

Это не хак, это возможный фикс, хотя мне больше нравится test -f.
Проверка test -x нужна для выявления исполняемости, а в данном случае исполняемость никого не интересует, ибо никто не собирается исполнять тестируемые файлы в том контексте, в котором проводится тестирование.

Да, и заодно пара пожеланий:
- ссылка там пусть лучше будет относительной, а не абсолютной;
- если в результате указанного в шебанге шелла не оказалось, хорошо бы вывести как минимум предупреждение.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107432</commentid>
    <comment_count>16</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 02:16:51 +0300</bug_when>
    <thetext>(В ответ на комментарий №15)
&gt; Не все программы имеют такое право.  И, обрати внимание, именно твоя программа
&gt; оказалась в той системе первой, кому это право понадобилось.  Зачем открывать
&gt; этот ящик раньше времени?

В каких каталогах можно создавать временные директории и гарантированно будет работать проверка на -x ?

&gt; &gt; Твоё решение ведёт к тому, что
&gt; &gt; они будут это делать в неожиданных местах вместо законного TMPDIR.
&gt; 
&gt; В неожиданных местах они будут неожиданно получать EROFS или EACCES.

От рута этих мест будет меньше чем у обычного пользователя.

&gt; Имей в виду наличие всяких ручек вроде selinux.

У нас его нет, а в дистрибутивах там где он есть (fedora) initrd создаётся в TMPDIR (dracut). И, не поверите, они тоже там проверяют наличие шелла и тоже через -x.

&gt; Почему ты не можешь этого гарантировать?

Потому что система модульная.

&gt; Это не хак, это возможный фикс, хотя мне больше нравится test -f.

Дим, тебе не нужно объяснять разницу между -x и -f.

&gt; Проверка test -x нужна для выявления исполняемости, а в данном случае
&gt; исполняемость никого не интересует, ибо никто не собирается исполнять
&gt; тестируемые файлы в том контексте, в котором проводится тестирование.

Разумеется это проверка важна. Я хочу быть уверенным, что в initrd я сделал симлинк на исполняемый файл, а не на обычный, потому что это ведёт к краху процесса загрузки.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107433</commentid>
    <comment_count>17</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 02:54:42 +0300</bug_when>
    <thetext>(In reply to comment #16)
&gt; В каких каталогах можно создавать временные директории и гарантированно будет
&gt; работать проверка на -x ?

Такую гарантию никто не даст.

&gt; &gt; &gt; Твоё решение ведёт к тому, что
&gt; &gt; &gt; они будут это делать в неожиданных местах вместо законного TMPDIR.
&gt; &gt; 
&gt; &gt; В неожиданных местах они будут неожиданно получать EROFS или EACCES.
&gt; 
&gt; От рута этих мест будет меньше чем у обычного пользователя.

А почему только рут?  Я хочу использовать make-initrd для создания рамдисков для контейнеров.  Это ведь совершенно непривилегированная операция.

&gt; &gt; Имей в виду наличие всяких ручек вроде selinux.
&gt; 
&gt; У нас его нет,

Это дело недолгого времени.

&gt; а в дистрибутивах там где он есть (fedora) initrd создаётся в
&gt; TMPDIR (dracut). И, не поверите, они тоже там проверяют наличие шелла и тоже
&gt; через -x.

Ну и зря.  В других дистрибутивах тоже делают ошибки и необоснованные допущения.

&gt; &gt; Почему ты не можешь этого гарантировать?
&gt; 
&gt; Потому что система модульная.

На модули можно накладывать ограничения.

&gt; &gt; Проверка test -x нужна для выявления исполняемости, а в данном случае
&gt; &gt; исполняемость никого не интересует, ибо никто не собирается исполнять
&gt; &gt; тестируемые файлы в том контексте, в котором проводится тестирование.
&gt; 
&gt; Разумеется это проверка важна. Я хочу быть уверенным, что в initrd я сделал
&gt; симлинк на исполняемый файл, а не на обычный, потому что это ведёт к краху
&gt; процесса загрузки.

Ты всё равно не можешь достверно установить будущую исполнимость файла в контексте рамдиска.
Наличие атрибута u+x -- это необходимое, но не достаточное условие исполнимости.
Проверка test -x не даёт гарантии исполнимости даже в нативном контексте, не говоря уже о чужом контексте.
Вот простой пример:
$ echo &apos;#!/missing&apos; &gt; sample &amp;&amp; chmod 700 sample &amp;&amp; test -x sample &amp;&amp; ./sample
-bash: ./sample: /missing: bad interpreter: No such file or directory
$ env -i strace -eexecve ./sample
execve(&quot;./sample&quot;, [&quot;./sample&quot;], [/* 0 vars */]) = -1 ENOENT (No such file or directory)
strace: exec: No such file or directory

Ты ведь знаешь, чем отличается проверка access(X_OK) от stat() с последующим тестом на S_IXUSR|S_IXGRP|S_IXOTH.  Какая тебе польза от этой разницы?

Вот код, о котором идёт речь:
for n in bash dash mksh ash; do
  [ -x ./bin/$n ] || continue
  ln -s /bin/$n ./bin/sh
  break
done

Возникают дополнительные вопросы:
- если ./bin/sh уже существует, то будет exit 1;
- если любой из вышеперечисленных файлов существует и является абсолютной ссылкой, то проверка test -x может пройти, в то время как файл, на который указывает ссылка, в образ не попадёт;
- как был получен этот список шеллов?
- зачем вообще нужен этот ./bin/sh?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107435</commentid>
    <comment_count>18</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 03:41:24 +0300</bug_when>
    <thetext>(В ответ на комментарий №17)
&gt; Такую гарантию никто не даст.

Значит использование TMPDIR правомерно т.к. оно предназначено для хранения временных файлов. Дополнительные ограничения на совести администратора.

&gt; А почему только рут?  Я хочу использовать make-initrd для создания рамдисков
&gt; для контейнеров.  Это ведь совершенно непривилегированная операция.

mkinitrd требовал его для создания устройств.
make-initrd требует его (как минимум) для доступа к /lib/modules.

&gt; Ну и зря.  В других дистрибутивах тоже делают ошибки и необоснованные
&gt; допущения.

На мой взгляд это правильное допущение, иначе можно дойти до того, что предётся монтировать tmpfs в рабочую директорию (и то не поможет), потому что любым файловым операциям нельзя доверять.

&gt; На модули можно накладывать ограничения.

Обоснуйте более веско необходимость накладывать ограничение в создании и выполнении временных скриптов и выполнении проверки на исполнимость. Это очень сильное ограничение и мне нужны очень веские доказательства того, что они необходимы.

&gt; Наличие атрибута u+x -- это необходимое, но не достаточное условие
&gt; исполнимости.

а find -perm +0111 даёт достаточную гарантию исполнимости ?

&gt; Ты ведь знаешь, чем отличается проверка access(X_OK) от stat() с последующим
&gt; тестом на S_IXUSR|S_IXGRP|S_IXOTH.  Какая тебе польза от этой разницы?

Мы не знаем под каким пользователем и в каком контексте будет выполняться создаваемый образ. Так как я не имею достаточной информации я использую более простую и нативную проверку (необходимую, но не достаточную).

&gt; Вот код, о котором идёт речь:
&gt; for n in bash dash mksh ash; do
&gt;   [ -x ./bin/$n ] || continue
&gt;   ln -s /bin/$n ./bin/sh
&gt;   break
&gt; done
&gt; 
&gt; Возникают дополнительные вопросы:
&gt; - если ./bin/sh уже существует, то будет exit 1;

Это ошибка. В следующей версии исправлю.

&gt; - если любой из вышеперечисленных файлов существует и является абсолютной
&gt; ссылкой, то проверка test -x может пройти, в то время как файл, на который
&gt; указывает ссылка, в образ не попадёт;

put-file копирует не только симлинк, но и то на что он указывает (copy_file()).

&gt; - как был получен этот список шеллов?

Это список шеллов, которые я смог вспомнить и которые поддерживают posix в достаточной мере чтобы выполнить скрипты initrd.

&gt; - зачем вообще нужен этот ./bin/sh?

Чтобы иметь возможность писать #!/bin/sh в initrd.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107437</commentid>
    <comment_count>19</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 03:51:29 +0300</bug_when>
    <thetext>К чему бы не привело это обсуждение, вы же все понимаете, что при поддержке модульности и при наличии хуков (сейчас они только внешние, но как знать что будет) гарантировать работоспособность initrd после сборки с noexec невозможно.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107438</commentid>
    <comment_count>20</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 04:04:20 +0300</bug_when>
    <thetext>(In reply to comment #18)
&gt; (В ответ на комментарий №17)
&gt; &gt; Такую гарантию никто не даст.
&gt; 
&gt; Значит использование TMPDIR правомерно т.к. оно предназначено для хранения
&gt; временных файлов. Дополнительные ограничения на совести администратора.

Да, но хранение и исполнение временных файлов -- это совершенно разные операции.

&gt; &gt; А почему только рут?  Я хочу использовать make-initrd для создания рамдисков
&gt; &gt; для контейнеров.  Это ведь совершенно непривилегированная операция.
&gt; 
&gt; mkinitrd требовал его для создания устройств.
&gt; make-initrd требует его (как минимум) для доступа к /lib/modules.

На тему этого доступа у нас, кстати, всё ещё висит баг #5969.
Ладно, тут мы отвлеклись от темы.

&gt; &gt; Ну и зря.  В других дистрибутивах тоже делают ошибки и необоснованные
&gt; &gt; допущения.
&gt; 
&gt; На мой взгляд это правильное допущение, иначе можно дойти до того, что предётся
&gt; монтировать tmpfs в рабочую директорию (и то не поможет), потому что любым
&gt; файловым операциям нельзя доверять.

Мы ведь говорим про совершенно реальную (и довольно распространённую в узких кругах) ситуацию.

&gt; &gt; На модули можно накладывать ограничения.
&gt; 
&gt; Обоснуйте более веско необходимость накладывать ограничение в создании и
&gt; выполнении временных скриптов и выполнении проверки на исполнимость. Это очень
&gt; сильное ограничение и мне нужны очень веские доказательства того, что они
&gt; необходимы.

У нас ещё никто никогда в базовой системе не исполнял временные файлы.

&gt; &gt; Наличие атрибута u+x -- это необходимое, но не достаточное условие
&gt; &gt; исполнимости.
&gt; 
&gt; а find -perm +0111 даёт достаточную гарантию исполнимости ?
&gt; 
&gt; &gt; Ты ведь знаешь, чем отличается проверка access(X_OK) от stat() с последующим
&gt; &gt; тестом на S_IXUSR|S_IXGRP|S_IXOTH.  Какая тебе польза от этой разницы?
&gt; 
&gt; Мы не знаем под каким пользователем и в каком контексте будет выполняться
&gt; создаваемый образ. Так как я не имею достаточной информации я использую более
&gt; простую и нативную проверку (необходимую, но не достаточную).

Проверка простая, с этим никто не спорит.  И с тем, что она не является панацеей, тоже все согласны.  Весь разговор о том, что эта проверка является не необходимой, а немного избыточной.  Накладываются ограничения, без следования которым всё работало бы правильно.

&gt; &gt; Вот код, о котором идёт речь:
&gt; &gt; for n in bash dash mksh ash; do
&gt; &gt;   [ -x ./bin/$n ] || continue
&gt; &gt;   ln -s /bin/$n ./bin/sh
&gt; &gt;   break
&gt; &gt; done
&gt; &gt; 
&gt; &gt; Возникают дополнительные вопросы:
&gt; 
&gt; &gt; - если любой из вышеперечисленных файлов существует и является абсолютной
&gt; &gt; ссылкой, то проверка test -x может пройти, в то время как файл, на который
&gt; &gt; указывает ссылка, в образ не попадёт;
&gt; 
&gt; put-file копирует не только симлинк, но и то на что он указывает (copy_file()).

А если и то, на что он указывает, тоже ссылка?  Например, /bin/bash, указывающий на bash3?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107439</commentid>
    <comment_count>21</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 04:15:57 +0300</bug_when>
    <thetext>(In reply to comment #19)
&gt; К чему бы не привело это обсуждение, вы же все понимаете, что при поддержке
&gt; модульности и при наличии хуков (сейчас они только внешние, но как знать что
&gt; будет) гарантировать работоспособность initrd после сборки с noexec невозможно.

Я не уверен, что можно гарантировать работоспособность initrd в принципе.
Хорошо бы гарантировать, что initrd не получится неработоспособным именно из-за noexec на $TMPDIR, а ещё лучше -- сделать так, чтобы noexec на $TMPDIR вообще не влиял на make-initrd.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107440</commentid>
    <comment_count>22</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 04:49:03 +0300</bug_when>
    <thetext>(В ответ на комментарий №20)
&gt; Да, но хранение и исполнение временных файлов -- это совершенно разные
&gt; операции.

Да. Но и выполнение временных скриптов тоже правомерная операция в которой нельзя отказать. Несколько примеров касающиеся исполнения чего-либо в рабочем каталоге: mkimage исполняет сгенерированные скрипты для модификации образа; hasher исполняет сгенерированные скрипты для выполнения команд внутри образа.

&gt; На тему этого доступа у нас, кстати, всё ещё висит баг #5969.
&gt; Ладно, тут мы отвлеклись от темы.


&gt; Мы ведь говорим про совершенно реальную (и довольно распространённую в узких
&gt; кругах) ситуацию.

Прощу привести доводы, почему 

&gt; У нас ещё никто никогда в базовой системе не исполнял временные файлы.

Исполнять скрипт и делать проверку на u+x разные вещи. И это всё равно не довод. Проблема #5969 не решена, но всё бывает в первый раз.

&gt; Проверка простая, с этим никто не спорит.  И с тем, что она не является
&gt; панацеей, тоже все согласны.  Весь разговор о том, что эта проверка является не
&gt; необходимой, а немного избыточной.  Накладываются ограничения, без следования
&gt; которым всё работало бы правильно.

В общем случае (следуя паранойе) проверка на -f ослабит конструкцию и тогда будет возможно положить симлинк /bin/bash который будет указывать на простой файл.
То что ты предлагаешь не решение, а маскировка проблемы: &quot;давайте не будем проверять на исполнимость т.к. проверка неудобна и пусть будет, что будет&quot;

&gt; А если и то, на что он указывает, тоже ссылка?  Например, /bin/bash,
&gt; указывающий на bash3?

В этом случае он должен скопировать все симлинки до bash3.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107441</commentid>
    <comment_count>23</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-05 05:05:19 +0300</bug_when>
    <thetext>(В ответ на комментарий №21)
&gt; Я не уверен, что можно гарантировать работоспособность initrd в принципе.

Согласен и поэтому я стараюсь не ослаблять проверки без особой нужды. Плохо само получится.

&gt; Хорошо бы гарантировать, что initrd не получится неработоспособным именно
&gt; из-за noexec на $TMPDIR, а ещё лучше -- сделать так, чтобы noexec на $TMPDIR
&gt; вообще не влиял на make-initrd.

Для этого проще всего вернуться к старому mkinitrd. Он не подразумевал расширения initrd ничем кроме копирования с разыменовыванием.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107442</commentid>
    <comment_count>24</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 05:07:34 +0300</bug_when>
    <thetext>Дублирую сюда часть приватного письма.

Есть программы, которым необходимо исполнять временные файлы, однако
такие программы либо не являются базовыми, либо у них есть ручки для
настройки.  Возьмём тот же rpm, который сохраняет и исполняет
%post-скрипты.  У него есть макрос %_tmppath, который реализует эту
настройку.  У каждого пользователя может быть определено своё значение
макроса %_tmppath.  Если ты _настаиваешь_ на том, что make-initrd нужно
уметь исполнять временные файлы, то сделай аналогичную ручку.
Например, можно зарезервировать для этих целей какую-нибудь переменную
среды, скажем, MKINITRD_TMPDIR.  Использовать $TMPDIR в безусловном
порядке плохо из-за того, что эта переменная слишком общего назначения,
и предназначена она в основном для определения места для _хранения_
временных файлов утилитами вроде sort(1), а не места для _выполнения_
временных файлов.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107443</commentid>
    <comment_count>25</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2010-03-05 05:09:54 +0300</bug_when>
    <thetext>(In reply to comment #23)
&gt; (В ответ на комментарий №21)
&gt; 
&gt; &gt; Хорошо бы гарантировать, что initrd не получится неработоспособным именно
&gt; &gt; из-за noexec на $TMPDIR, а ещё лучше -- сделать так, чтобы noexec на $TMPDIR
&gt; &gt; вообще не влиял на make-initrd.
&gt; 
&gt; Для этого проще всего вернуться к старому mkinitrd. Он не подразумевал
&gt; расширения initrd ничем кроме копирования с разыменовыванием.

На этой стадии развития уже проще пропатчить make-initrd.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107479</commentid>
    <comment_count>26</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-06 17:42:43 +0300</bug_when>
    <thetext>По результатам приватного общения:

Добавлена поддержка переменной окружения INITRD_WORKDIR, которая определяет каталог где будет создаваться образ. Логика следующая:

WORKDIR=&quot;${INITRD_WORKDIR-}&quot;
WORKDIR=&quot;${WORKDIR:-${TMPDIR-}}&quot;
WORKDIR=&quot;${WORKDIR:-/tmp}&quot;

Плюс добавлена проверка на &apos;noexec&apos; опцию.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107490</commentid>
    <comment_count>27</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2010-03-07 19:31:41 +0300</bug_when>
    <thetext>(In reply to comment #26)
&gt; Плюс добавлена проверка на &apos;noexec&apos; опцию.
Спасибо!  С меня причитается за вредность :)

(In reply to comment #17)
&gt; &gt; Разумеется это проверка важна. Я хочу быть уверенным, что в initrd я сделал
&gt; &gt; симлинк на исполняемый файл, а не на обычный, потому что это ведёт к краху
&gt; &gt; процесса загрузки.
Так в багу вчитайся -- именно этой &quot;уверенностью&quot; в виде некорректного теста и привёл ко краху процесса загрузки.

&gt; Проверка test -x не даёт гарантии исполнимости даже в нативном контексте, не
&gt; говоря уже о чужом контексте.
Мало того, /bin/sh может оказаться вообще не командным интерпретатором -- и что с того?  Я бы если уж хочется обеспечить исполнимость в данном качестве -- то:
1) попытался бы выполнить простейший тест вида [ &quot;$(sh -c &quot;true &amp;&amp; echo yes&quot;) = &quot;yes&quot; ] (на что могут быть архитектурные ограничения -- или нет?)
2) сделал бы chmod +x на уложенный для формирования образа экземпляр.

(In reply to comment #18)
&gt; Значит использование TMPDIR правомерно т.к. оно предназначено для хранения
&gt; временных файлов. Дополнительные ограничения на совести администратора.
Ну ты даёшь.  Вот уж ради собственной блажи наказывать системного администратора, предпринявшего _разумную_ меру для его собственной системы -- это непрофессионализм.

&gt; &gt; А почему только рут?
&gt; make-initrd требует его (как минимум) для доступа к /lib/modules.
У меня ещё есть надежда сделать control для /boot и /lib/modules. :)

&gt; Обоснуйте более веско необходимость накладывать ограничение в создании и
&gt; выполнении временных скриптов и выполнении проверки на исполнимость. Это очень
&gt; сильное ограничение и мне нужны очень веские доказательства того, что они
&gt; необходимы.
Я как администратор веб-серверов порой предпочитаю отбирать у apache возможность записи в /tmp, и считаю возможность для хоста смонтировать его с noexec большим плюсом.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107491</commentid>
    <comment_count>28</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-07 19:51:24 +0300</bug_when>
    <thetext>(В ответ на комментарий №27)

Как я уже сказал, поведение make-initrd не поменяется. Появилась проверка на корректность &quot;test -x&quot;, выполнение скриптов в workdir и если таких возможностей у workdir нет, то будет отказ что-либо создавать в таком рабочем каталоге. Плюс тем, у кого такой супер безопасный каталог /tmp, сделана переменная, где все условия будут выполняться.

Так что искать небезопасный каталог? доступный вызвавшему make-initrd, на безопасном сервере всё равно предётся, чтобы вы не говорили.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107492</commentid>
    <comment_count>29</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-07 19:52:41 +0300</bug_when>
    <thetext>(В ответ на комментарий №27)

Как я уже сказал, поведение make-initrd не поменяется. Появилась проверка на корректность &quot;test -x&quot;, выполнение скриптов в workdir и если таких возможностей у workdir нет, то будет отказ что-либо создавать в таком рабочем каталоге. Плюс тем, у кого такой супер безопасный каталог /tmp, сделана переменная, где все условия будут выполняться.

Так что искать небезопасный каталог, доступный вызвавшему make-initrd, на безопасном сервере всё равно предётся, чтобы вы не говорили.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107493</commentid>
    <comment_count>30</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-03-07 20:10:29 +0300</bug_when>
    <thetext>(В ответ на комментарий №27)
&gt; &gt; Значит использование TMPDIR правомерно т.к. оно предназначено для хранения
&gt; &gt; временных файлов. Дополнительные ограничения на совести администратора.
&gt; Ну ты даёшь.  Вот уж ради собственной блажи наказывать системного
&gt; администратора, предпринявшего _разумную_ меру для его собственной системы --
&gt; это непрофессионализм.

Хочу выделить это замечание, но оставлю его без комментариев дабы не усиливать обиду у обиженных и не обижать новых читателей.

&gt; считаю возможность для хоста смонтировать его с noexec большим плюсом.

Считай. Теперь ты можешь монтировать хоть всю систему в readonly и сам придумывать где генерировать initrd.

В общем, тему считаю исчерпанной.
Ждите нового релиза.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>115694</commentid>
    <comment_count>31</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2010-11-25 13:52:14 +0300</bug_when>
    <thetext>*** Bug 24641 has been marked as a duplicate of this bug. ***</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139918</commentid>
    <comment_count>32</comment_count>
    <who name="Vitaly Lipatov">lav</who>
    <bug_when>2013-04-27 13:12:08 +0400</bug_when>
    <thetext>Написали много, а заявленную проблему так и не решили.
1. Такое поведение make-initrd по умолчанию запрещает использование noexec для /tmp (приводя к негрузящейся системе)
2. Вовсе не надо было так упираться в проверку исполнимости через test -x, она ничего сильного не делает, можно было и объехать.

P.S.
Если make-initrd ничего не создаёт вследствие какой-либо ошибки, grub потом получает запись для загрузки ядра просто без initrd.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139921</commentid>
    <comment_count>33</comment_count>
    <who name="Dmitry V. Levin">ldv</who>
    <bug_when>2013-04-27 17:32:29 +0400</bug_when>
    <thetext>Я бы в данном конкретном случае все равно заменил бы проверки

[ ! -x ./bin/sh ]
и
[ -x ./bin/$n ]

на

[ -z &quot;$(find -L ./bin/sh -maxdepth 0 -type f -perm -u=x 2&gt;/dev/null)&quot; ]
и
[ -n &quot;$(find -L ./bin/$n -maxdepth 0 -type f -perm -u=x 2&gt;/dev/null)&quot; ]

соответственно.

Но сейчас там уже check_noexec, что обессмысливает эту замену, и я уже везде, где надо, давно использую INITRD_WORKDIR.
Поскольку make-initrd непременно хочет иметь возможность исполнять временные файлы, это CLOSED FIXED.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>