На 5.5.6-un-def-alt1 в соответствии с https://www.altlinux.org/AltHa и Documentation/admin-guide/LSM/AltHa.rst настроил блокировку интерпретатор, но в дефолтной рекомендуемой конфигурации нет проблем запустить заблокированный интерпретатор: [root@alt-xfce ~]# sysctl -w kernel.altha.rstrscript.enabled=1 [root@alt-xfce ~]# sysctl -w kernel.altha.rstrscript.interpreters=/usr/bin/python:/usr/bin/python3:/usr/bin/perl:/usr/bin/tclsh [root@alt-xfce ~]# python3 -bash: /usr/bin/python3: Операция не позволена [root@alt-xfce ~]# dmesg | tail -n 1 [ 162.090737] AltHa/RestrScript: /usr/bin/python3 is blocked to run directly by 0 [root@alt-xfce ~]# /lib64/ld-linux-x86-64.so.2 /usr/bin/python3 Python 3.7.4 (default, Oct 18 2019, 08:46:11) [GCC 8.3.1 20190507 (ALT Sisyphus 8.3.1-alt5)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> Но при этом: [root@alt-xfce ~]# setarch --addr-no-randomize /usr/bin/python3 setarch: невозможно выполнить /usr/bin/python3: Операция не позволена [root@alt-xfce ~]# dmesg | tail -n 1 [ 597.621353] AltHa/RestrScript: /usr/bin/python3 is blocked to run directly by 0 [root@alt-xfce ~]# В коде вижу, что производится сравнение путей: > if (path_equal(&bprm->file->f_path, &node->path)) { http://git.altlinux.org/gears/k/kernel-image-un-def.git?p=kernel-image-un-def.git;a=blob;f=security/altha/altha_lsm.c;h=7d1cc8f8a1a7ada31975473935a620e8ff2f772d;hb=HEAD#l260 Как это красиво решить, я пока не придумал.
Спасибо, будем думать
На мой взгляд, самое простое и разумное -- добавить /lib64/ld-linux-x86-64.so.2 и /lib/ld-linux.so.2 (ну и на других платформах соответственно) в списки ограничений altha. Обычно они не запускаются напрямую. Что-то, скорее всего, сломается (как и при блокировке прямого запуска интерпретаторов вообще), но быстрый тест на рабочей станции 9 не показал регрессий. Спасибо за сообщение, эту информацию обязательно надо будет внести в документацию
Я тоже не придумал, чем на типовой рабочей станции может помешать запрет запуска ld-linux*. Но здесь хочется выяснить, почему при запуске через ld-linux не происходит блокировки, через strace видны одинаковые системные вызовы: [root@alt-xfce ~]# strace /lib64/ld-linux-x86-64.so.2 /usr/bin/python3 2>&1 | grep /usr/bin/python3 execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2", "/usr/bin/python3"], 0x7fff7c00c658 /* 45 vars */) = 0 openat(AT_FDCWD, "/usr/bin/python3", O_RDONLY|O_CLOEXEC) = 3 <...> [root@alt-xfce ~]# strace /bin/sh /usr/bin/python3 2>&1 | grep /usr/bin/python3 execve("/bin/sh", ["/bin/sh", "/usr/bin/python3"], 0x7ffe002e9148 /* 45 vars */) = 0 openat(AT_FDCWD, "/usr/bin/python3", O_RDONLY) = 3 <...> [root@alt-xfce ~]# В первом случае блокировка не срабатывает, во втором срабатывает. Надеюсь, через user mode linux получится проследить, как так получается. Сборки uml с altha у меня уже есть, пока не запускал и не уверен, что под uml LSM будут работать.
(Ответ для Михаил Новоселов на комментарий #3) > Я тоже не придумал, чем на типовой рабочей станции может помешать запрет > запуска ld-linux*. Но здесь хочется выяснить, почему при запуске через > ld-linux не происходит блокировки, через strace видны одинаковые системные > вызовы: > [root@alt-xfce ~]# strace /lib64/ld-linux-x86-64.so.2 /usr/bin/python3 2>&1 > | grep /usr/bin/python3 > execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2", > "/usr/bin/python3"], 0x7fff7c00c658 /* 45 vars */) = 0 > openat(AT_FDCWD, "/usr/bin/python3", O_RDONLY|O_CLOEXEC) = 3 > <...> > [root@alt-xfce ~]# strace /bin/sh /usr/bin/python3 2>&1 | grep тут должно быть strace /bin/sh -с /usr/bin/python3 Что даёт execve("/bin/sh", ["/bin/sh", "-c", "/usr/bin/python"], 0x7ffd0d05fa60 /* 64 vars */) = 0 execve("/usr/bin/python", ["/usr/bin/python"], 0x775700 /* 64 vars */) = 0 А в случае запуска через ld-linux, второго exec нет
AltHa привязывается к LSM-хукам bprm_set_creds и inode_unlink. А вот в политиках IMA обычно отслеживают bprm_check и mmap_file: https://en.opensuse.org/SDB:Ima_evm#Configuration_of_the_IMA_Policy_and_dracut_Early_Init <...> appraise func=BPRM_CHECK fowner=0 appraise_type=imasig appraise func=BPRM_CHECK euid=0 appraise_type=imasig appraise func=FILE_MMAP fowner=0 mask=MAY_EXEC appraise_type=imasig appraise func=FILE_MMAP euid=0 mask=MAY_EXEC appraise_type=imasig <...> Require all files that are directly executed or memory mapped with execute permission to carry a digital signature При запуске через rtld выполняется mmap с PROT_EXEC 2 раза: $ strace /lib64/ld-linux-x86-64.so.2 /bin/true 2>&1 | grep mmap | grep PROT_EXEC mmap(0x7f72dd6ca000, 16384, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f72dd6ca000 mmap(0x7f72dd4a5000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f72dd4a5000 Без rtld - один раз: $ strace /bin/true 2>&1 | grep mmap | grep PROT_EXEC mmap(0x7f96b4d5f000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f96b4d5f000 Может быть, в АльтХе стоит ловить mmap с PROT_EXEC, как это делает IMA?
Может ли быть блокировка mmap() с PROT_EXEC полезна еще чем-то, кроме отсутствия необходимости блокировать rtld как интерпретатор?
(In reply to Михаил Новоселов from comment #5) > $ strace /bin/true 2>&1 | grep mmap | grep PROT_EXEC > mmap(0x7f96b4d5f000, 1540096, PROT_READ|PROT_EXEC, > MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f96b4d5f000 Меня насторожил этот пример, потому что альтовый /bin/true не использует rtld, и mmap ему делать совершенно незачем. Но я на всякий случай проверил: $ env -i strace -v /bin/true execve("/bin/true", ["/bin/true"], []) = 0 exit_group(0) = ? +++ exited with 0 +++ Наверное, /bin/true не очень подходит в качестве иллюстрации, лучше /bin/cat </dev/null
> Может быть, в АльтХе стоит ловить mmap с PROT_EXEC, как это делает IMA? Я сомневаюсь, что в хуке на mmap удастся отличить запуск бинарника как интерпертатор и прямой запуск. > необходимости блокировать rtld как интерпретатор? Вообще говоря, запрет прямого запуска rtld, запуска не в качестве интерпретатора выглядит неплохой идеей для систем, в которых это предполагается использовать.
(Ответ для Dmitry V. Levin на комментарий #7) > Меня насторожил этот пример, потому что альтовый /bin/true не использует > rtld, и mmap ему делать совершенно незачем. Но я на всякий случай проверил: > $ env -i strace -v /bin/true > execve("/bin/true", ["/bin/true"], []) = 0 > exit_group(0) = ? > +++ exited with 0 +++ > > Наверное, /bin/true не очень подходит в качестве иллюстрации, лучше /bin/cat > </dev/null Да, пример был не с Альта, спасибо за уточнение. (Ответ для Anton V. Boyarshinov на комментарий #8) > > Может быть, в АльтХе стоит ловить mmap с PROT_EXEC, как это делает IMA? > > Я сомневаюсь, что в хуке на mmap удастся отличить запуск бинарника как > интерпертатор и прямой запуск. Разумно. Надо сказать, звучит как повод в rpm автоматически заменять #!/usr/bin/env foo на реальный путь в шебангах.
Смотрю, в исходниках ядра теперь упомянут ld-linux, но на вики не был. Добавил про него в статью https://www.altlinux.org/AltHa P.S. В исходниках https://git.altlinux.org/gears/k/kernel-image-un-def.git?p=kernel-image-un-def.git;a=blob;f=Documentation/admin-guide/LSM/AltHa.rst;h=beda40601c9e72fb1b9ed17e5492a3223a707452;hb=HEAD#l35 кавычки стоят на одно слово правее, чем нужно, мне кажется: "Adding ld-linux into blocking list prevents running interpreters via ``ld-linux interpreter``"