Saya mencoba menjalankan ADB pada server linux dengan banyak pengguna di mana saya tidak melakukan root (untuk bermain dengan emulator android saya). Adb daemon menulis log-nya ke file /tmp/adb.log
yang sayangnya tampaknya sulit dikodekan ke dalam ADB dan situasi ini tidak akan berubah .
Jadi, adb gagal untuk dijalankan, memberikan kesalahan yang jelas: cannot open '/tmp/adb.log': Permission denied
. File ini dibuat oleh pengguna lain dan /tmp
sedikit lengket. Jika saya memulai adb dengan adb nodaemon server
membuatnya menulis ke stdout, tidak ada kesalahan terjadi (saya juga mengatur port-nya ke nilai unik untuk menghindari konflik).
Pertanyaan saya adalah: adakah cara untuk membuat ADB menulis ke file lain /tmp/adb.log
? Secara umum, adakah cara untuk membuat semacam symlink khusus proses? Saya ingin mengalihkan semua akses file /tmp/adb.log
ke, katakanlah, file ~/tmp/adb.log
.
Sekali lagi, saya tidak melakukan root pada server, jadi chroot
, mount -o rbind
dan chmod
bukan opsi yang valid. Jika memungkinkan, saya ingin tidak memodifikasi sumber ADB, tetapi tentu saja jika tidak ada solusi lain, saya akan melakukannya.
PS Untuk kasus ADB spesifik saya bisa resor untuk berjalan adb nodaemon server
dengan nohup
dan output redirection, tapi pertanyaan umum masih relevan.
/tmp/adb.log
, atau bahkan me-mount privasinya sendiri/tmp
. lakukanman unshare
danman namespaces
danman nsenter
.LD_PRELOAD
trik, meski itu akan lebih rumit./home/$USER/tmp/adb.log
dan membangun kembali adb :)Jawaban:
Berikut ini adalah contoh yang sangat sederhana dari menggunakan
util-linux
'sunshare
untuk menempatkan proses di dalam mount namespace pribadi dan memberikannya pandangan yang berbeda dari sistem file yang sama dengan yang dimiliki induknya:Anda dapat memberikan proses tampilan pribadi dari sistem file dengan
unshare
utilitas pada sistem linux terbaru, meskipun fasilitas mount namespace sendiri sudah cukup matang untuk seluruh seri 3.x kernel. Anda dapat memasukkan ruang nama yang sudah ada sebelumnya dari semua jenis dengannsenter
utilitas dari paket yang sama, dan Anda bisa mencari tahu lebih banyak denganman
.sumber
unshare
semua jenis ruang nama - untuk memasukkan ruang nama pengguna. dan sehingga pengguna Anda dapat menjalankan namespace di mana ia memiliki akses root dan apa pun yang dilakukannya di dalam yang pengguna root mungkin gagal tidak memengaruhi namespace induk. dengan kata lain, mount namespace dapat disematkan di dalam namespace pengguna. Anda benar-benar perlu membacaman
halaman - halaman itu. semakin dalam. inilah tepatnya caradocker
dansytemd-nspawn
kerjanya.runuser
utilitas yang dapat digunakanunshare
, dan jika Anda tetap dapat menulis program yang dikompilasi, tidak ada alasan Anda tidak dapat menggunakanunshare()
syscall untuk melakukan hal yang sama, atau bahkan hanyasystem()
dengan biner suid.LD_PRELOAD tidak terlalu sulit, dan Anda tidak perlu menjadi root. Sisipkan rutin C Anda sendiri yang disebut bukan yang asli
open()
di perpustakaan C. Rutin Anda memeriksa apakah file yang dibuka adalah "/tmp/adb.log" dan memanggil file yang sebenarnya terbuka dengan nama file yang berbeda. Inilah shim_open.c Anda:Kompilasi dengan
gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
dan mengujinya dengan memasukkan/tmp/myadb.log
dan menjalankan sesuatuLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
. Kemudian coba LD_PRELOAD di adb.sumber
Operation not permitted
). Saya harap ituopen
cukup untuk ditangani, tetapi akhirnya, menambahkanunlink
ke pawang ini tidak sulit.unshare
juga, jadi kita semua mendapat untung!