Я пытаюсь запустить ADB на сервере Linux с несколькими пользователями, где я не являюсь пользователем root (чтобы играть с моим эмулятором Android). Демон adb записывает свои логи в файл, /tmp/adb.log
который, к сожалению, жестко запрограммирован в ADB, и эта ситуация не изменится .
Таким образом, ADB не в состоянии бежать, давая очевидную ошибку: cannot open '/tmp/adb.log': Permission denied
. Этот файл создан другим пользователем и /tmp
имеет прикрепленный бит. Если я начну adb с adb nodaemon server
записи в stdout, ошибок не будет (я также установил для его порта уникальное значение, чтобы избежать конфликтов).
Мой вопрос: есть ли способ заставить ADB записать в другой файл, чем /tmp/adb.log
? В более общем смысле, есть ли способ создать своего рода символьную ссылку для конкретного процесса? Я хочу перенаправить все обращения к файлам /tmp/adb.log
, скажем, к файлу ~/tmp/adb.log
.
Опять же , я не корень на сервере, поэтому chroot
, mount -o rbind
и chmod
не являются допустимыми вариантами. Если возможно, я бы не хотел изменять источники ADB, но, конечно, если других решений нет, я сделаю это.
PS Для конкретного случая ADB я могу прибегнуть к работе adb nodaemon server
с nohup
перенаправлением вывода и выводу, но общий вопрос все еще актуален.
/tmp/adb.log
, или даже смонтировать его собственный приватный файл/tmp
. делайman unshare
иman namespaces
иman nsenter
.LD_PRELOAD
хитрости, хотя это будет сложнее./home/$USER/tmp/adb.log
и перестроить adb :)Ответы:
Вот очень простой пример использования
util-linux
's',unshare
чтобы поместить процесс в приватное пространство имен монтирования и дать ему другое представление о той же файловой системе, которую имеет его родительский объект:Вы можете предоставить процессу частное представление своей файловой системы с помощью
unshare
утилиты в современных системах linux, хотя сама функция пространства имен mount была достаточно зрелой для всей серии ядер 3.x. Вы можете ввести ранее существующие пространства имен всех видов с помощьюnsenter
утилиты из одного пакета, и вы можете узнать больше с помощьюman
.источник
unshare
все виды пространств имен - чтобы включить пространство имен пользователя. и поэтому ваш пользователь может запустить пространство имен, в котором у него есть root-доступ, и все, что он делает внутри, что может испортить корневой пользователь, не влияет на родительское пространство имен. другими словами, пространство имен монтирования может быть встроено в пространство имен пользователя. вам действительно нужно прочитать этиman
страницы. это становится глубоким. это именно такdocker
иsytemd-nspawn
работает.runuser
утилита, с которой можно работатьunshare
, и если вы все равноunshare()
готовы писать скомпилированные программы, нет никаких причин, по которым вы не могли бы использовать syscall для того же или даже простоsystem()
с suid-двоичным файлом.LD_PRELOAD не слишком сложен, и вам не нужно быть пользователем root. Вставьте свою собственную подпрограмму C, которая вызывается вместо реальной
open()
в библиотеке C. Ваша процедура проверяет, является ли открываемый файл "/tmp/adb.log", и вызывает реальное открытие с другим именем файла. Вот ваш shim_open.c:Скомпилируйте его
gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
и протестируйте,/tmp/myadb.log
запустив и запустивLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
. Затем попробуйте LD_PRELOAD на ADB.источник
Operation not permitted
). Я надеюсь, что этогоopen
достаточно для обработки, но, наконец, добавитьunlink
этот обработчик не сложно.unshare
, поэтому мы все выиграли!