Próbuję uruchomić ADB na serwerze Linux z wieloma użytkownikami, na których nie jestem rootem (aby grać z moim emulatorem Androida). Demon adb zapisuje swoje dzienniki do pliku, /tmp/adb.log
który niestety wydaje się być zakodowany na stałe w ADB i ta sytuacja się nie zmieni .
Więc adb nie udaje się uruchomić, co daje oczywisty błąd: cannot open '/tmp/adb.log': Permission denied
. Ten plik jest tworzony przez innego użytkownika i /tmp
ma trochę lepką wersję. Jeśli zacznę adb od zmuszenia adb nodaemon server
go do zapisu na standardowe wyjście, nie wystąpią żadne błędy (ustawiłem również jego port na unikalną wartość, aby uniknąć konfliktów).
Moje pytanie brzmi: czy jest jakiś sposób, aby ADB zapisał do innego pliku niż /tmp/adb.log
? Mówiąc bardziej ogólnie, czy istnieje sposób na stworzenie pewnego rodzaju dowiązania symbolicznego specyficznego dla procesu? Chcę przekierować wszystkie dostępy do plików /tmp/adb.log
, mówiąc, do pliku ~/tmp/adb.log
.
Znowu, nie jestem root na serwerze, tak chroot
, mount -o rbind
i chmod
nie są poprawne opcje. Jeśli to możliwe, nie chciałbym modyfikować źródeł ADB, ale na pewno, jeśli nie będzie innych rozwiązań, zrobię to.
PS W konkretnym przypadku ADB mogę skorzystać adb nodaemon server
z nohup
przekierowania i wyjścia, ale ogólne pytanie jest nadal aktualne.
/tmp/adb.log
, a nawet zamontować własny prywatny plik/tmp
. zrobićman unshare
iman namespaces
iman nsenter
.LD_PRELOAD
sztuczki, choć byłoby to bardziej skomplikowane./home/$USER/tmp/adb.log
Odpowiedzi:
Oto bardzo prosty przykład użycia
util-linux
„yunshare
umieścić proces w obszarze nazw prywatnej zamontować i nadać mu inny widok tego samego systemu plików, jego rodzic ma obecnie:Możesz nadać procesowi prywatny widok jego systemu plików za pomocą
unshare
narzędzia w aktualnych systemach Linux, chociaż samo narzędzie przestrzeni nazw montowania jest dość dojrzałe dla całej serii jądra 3.x. Możesz wprowadzić wcześniej istniejące przestrzenie nazw wszelkiego rodzaju za pomocąnsenter
narzędzia z tego samego pakietu, i możesz dowiedzieć się więcej za pomocąman
.źródło
unshare
wszelkiego rodzaju przestrzeni nazw - aby uwzględnić przestrzeń nazw użytkownika. a więc użytkownik może uruchomić przestrzeń nazw, w której ma dostęp do konta root, a wszystko, co zrobi to, co użytkownik root może spieprzyć, nie wpływa na nadrzędną przestrzeń nazw. innymi słowy, przestrzeń nazw montowania może być osadzona w przestrzeni nazw użytkownika. naprawdę musisz przeczytać teman
strony. robi się głęboki. tak właśnie działadocker
isytemd-nspawn
działa.runuser
narzędzie, z którego można korzystaćunshare
, a jeśli i tak jesteś otwarty na pisanie skompilowanych programów, nie ma powodu, dla którego nie mógłbyś użyć tego poleceniaunshare()
syscall, aby zrobić to samo, a nawet po prostusystem()
z suid binary.LD_PRELOAD nie jest zbyt trudny i nie musisz być rootem. Wstaw swoją własną procedurę C, która jest wywoływana zamiast rzeczywistej
open()
w bibliotece C. Procedura sprawdza, czy plik do otwarcia to „/tmp/adb.log” i wywołuje rzeczywiste otwarcie z inną nazwą pliku. Oto twój shim_open.c:Skompiluj
gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
i przetestuj,/tmp/myadb.log
uruchamiając cośLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
. Następnie spróbuj LD_PRELOAD na adb.źródło
Operation not permitted
). Mam nadzieję, żeopen
to wystarczy, ale w końcu dodanieunlink
tego modułu obsługi nie jest trudne.unshare
również, więc wszyscy zyskujemy!