Возможно ли подделка определенного пути для процесса?

Я пытаюсь запустить 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 , говоря, файл ~/tmp/adb.log .

Опять же, я не root на сервере, поэтому chroot , mount -o rbind и chmod являются недопустимыми. Если возможно, я бы хотел не изменять источники АБР, но, конечно, если нет других решений, я сделаю это.

PS Для конкретного случая ADB я могу прибегнуть к adb nodaemon server с перенаправлением nohup и вывода, но общий вопрос по-прежнему имеет значение.

Вот очень простой пример использования util-linux для unshare процесса в частное пространство имен монтирования и предоставление ему другого представления о той же файловой системе, в которой у его родителя в настоящее время:

 { cd /tmp #usually a safe place for this stuff echo hey >file #some echo there >file2 #evidence sudo unshare -m sh -c ' #unshare requires root by default mount -B file2 file #bind mount there over hey cat file #show it kill -TSTP "$$" #suspend root shell and switch back to parent umount file #unbind there cat file' #show it cat file #root shell just suspended fg #bring it back cat file2 #round it off } 

 there #root shell hey #root shell suspended hey #root shell restored there #rounded 

Вы можете предоставить частному виду своей файловой системы частную систему с помощью утилиты unshare для современных систем Linux, хотя сама установка пространства имен mount была достаточно зрелой для всей серии ядер 3.x. Вы можете вводить существующие пространства имен всех видов с nsenter утилиты nsenter из того же пакета, и вы можете узнать больше с man .

LD_PRELOAD не слишком сложно, и вам не нужно быть root. Вставьте свою собственную подпрограмму C, которая вызывается вместо реального open() в библиотеке C. Ваша программа проверяет, открывается ли файл «/tmp/adb.log» и вызывает реальное открытие с другим именем файла. Вот ваш shim_open.c:

 /* * capture calls to a routine and replace with your code * gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c * LD_PRELOAD=/.../shim_open.so cat /tmp/adb.log */ #define _FCNTL_H 1 /* hack for open() prototype */ #define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <dlfcn.h> #define OLDNAME "/tmp/adb.log" #define NEWNAME "/tmp/myadb.log" int open(const char *pathname, int flags, mode_t mode){ static int (*real_open)(const char *pathname, int flags, mode_t mode) = NULL; if (!real_open) { real_open = dlsym(RTLD_NEXT, "open"); char *error = dlerror(); if (error != NULL) { fprintf(stderr, "%s\n", error); exit(1); } } if (strcmp(pathname,OLDNAME)==0) pathname = NEWNAME; fprintf(stderr, "opening: %s\n", pathname); return real_open(pathname, flags, mode); } 

Скомпилируйте его с помощью 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.