у меня есть librandom.so
библиотека и main
выполнимый, который был составлен следующим образом:
$ clang++ -o main main.o -lrandom -L. -Wl,-rpath,"\$ORIGIN"
Они оба находятся в одном каталоге. поскольку main
имеет $ORIGIN
в его rpath
работает нормально — ./main
возвращается без ошибок.
Теперь я устанавливаю main
бежать с setuid
как root
:
$ sudo chown root main
$ sudo chmod a+s main
$ ./main
Я ожидал main
потерпеть неудачу с $ORIGIN
не расширяется в setuid
Приложения. Удивительно, но это работает.
Если я бегу main
из другого каталога, однако, это делает потерпеть неудачу как ожидалось
$ cd /tmp
$ /path/to/main
/path/to/main: error while loading shared libraries: librandom.so: cannot open shared object file: No such file or directory
Почему это работает, когда я бегу main
из его директории?
Я ожидал, что main потерпит неудачу, поскольку $ ORIGIN не раскрывается в приложениях setuid.
Удивительно, но это работает.
Glibc имеет долгую историю расширения $ORIGIN
даже для suid-файлов (см., например, CVE-2010-3847). Мотивация этого заключается в том, что suid двоичные файлы, которые используют $ORIGIN
поскольку rpath не работают по дизайну, поэтому разработчикам Glibc никогда не удавалось исправить это. Некоторые нижестоящие дистрибутивы предоставили патчи поверх стандартного Glibc, которые отключают расширение ORIGIN, поэтому точная ситуация зависит от вашего дистрибутива.
Достаточно смешно, только отдельно стоящий $ORIGIN
будет расширен — если вы замените его, например, на $ORIGIN/libs
это начнет терпеть неудачу.
Почему это работает, когда я запускаю main из каталога, в котором он находится?
Как только вы переместите свой файл, $ ORIGIN развернется в другую папку, в которой больше нет необходимой библиотеки.
Других решений пока нет …