為什麼 chroot 在現有文件上獲得 ENOENT?
;TL-DR -**答:**因為缺少動態連結器 ld-linux-x86-64.so.2。
我已經
-ro,loop
在/mnt/foo
.它包含以下內容(
/mnt/foo
是掛載點):-rwxr-xr-x 1 根 110088 2013 年 1 月 17 日 /mnt/foo/bin/ls -rw-r--r-- 1 root root 5212 jul 23 09:35 /mnt/foo/etc/ld.so.cache -rw-r--r-- 1 root root 5 jul 23 09:35 /mnt/foo/etc/ld.so.conf -rw-r--r-- 1 根根 31168 maj 23 2013 /mnt/foo/lib/libacl.so.1 -rw-r--r-- 1 根 18624 maj 20 2013 /mnt/foo/lib/libattr.so.1 -rwxr-xr-x 1 根 1853400 okt 12 2013 /mnt/foo/lib/libc.so.6 -rw-r--r-- 1 根 14664 okt 12 2013 /mnt/foo/lib/libdl.so.2 -rw-r--r-- 1 根 256224 2013 年 3 月 11 日 /mnt/foo/lib/libpcre.so.3 -rwxr-xr-x 1 根 135757 okt 12 2013 /mnt/foo/lib/libpthread.so.0 -rw-r--r-- 1 根根 31760 okt 12 2013 /mnt/foo/lib/librt.so.1 -rw-r--r-- 1 根 134224 maj 23 2013 /mnt/foo/lib/libselinux.so.1
/mnt/foo/etc/ld.so.conf
僅包含一行(包括換行符)/lib
。在創建文件系統之前,我將
ldconfig -r ${TOPDIR}
where${TOPDIR}
resolved 執行到現在安裝在/mnt/foo
. Astrings
on/mnt/foo/etc/ld.so.cache
顯示它包含諸如此類/lib/libpcre.so.3
的字元串,因此我認為共享庫沒有問題。我認為這一定是我忽略的一些愚蠢的事情,但我自己無法弄清楚為什麼一個簡單的
chroot /mnt/foo /bin/ls
不起作用。
readelf -d /mnt/foo/bin/ls | grep NEEDED
根據需要顯示這些庫:0x0000000000000001(需要)共享庫:[libselinux.so.1] 0x0000000000000001(需要)共享庫:[librt.so.1] 0x0000000000000001(需要)共享庫:[libacl.so.1] 0x0000000000000001(需要)共享庫:[libc.so.6]
最後,
strace
顯示這一點:chroot("/mnt/foo") = 0 chdir ("/") = 0 execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (沒有這樣的文件或目錄)
這是完整的 strace chroot:
# strace -f chroot /mnt/foo /bin/ls execve("/usr/sbin/chroot", ["chroot", "/mnt/foo", "/bin/ls"], [/* 32 vars */]) = 0 brk(0) = 0x1985000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (沒有那個文件或目錄) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115ac8000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (沒有這樣的文件或目錄) 打開(“/etc/ld.so.cache”,O_RDONLY|O_CLOEXEC)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=96457, ...}) = 0 mmap(NULL, 96457, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc115ab0000 關閉(3)= 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (沒有那個文件或目錄) 打開(“/lib/x86_64-linux-gnu/libc.so.6”,O_RDONLY|O_CLOEXEC)= 3 讀(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\36 \2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1853400, ...}) = 0 mmap(NULL, 3961912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc1154e0000 mprotect(0x7fc11569d000, 2097152, PROT_NONE) = 0 mmap(0x7fc11589d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7fc11589d000 mmap(0x7fc1158a3000, 17464, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc1158a3000 關閉(3)= 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115aaf000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115aad000 arch_prctl(ARCH_SET_FS, 0x7fc115aad740) = 0 mprotect(0x7fc11589d000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7fc115aca000, 4096, PROT_READ) = 0 munmap(0x7fc115ab0000, 96457) = 0 brk(0) = 0x1985000 brk(0x19a6000) = 0x19a6000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=8463952, ...}) = 0 mmap(NULL, 8463952, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc114ccd000 關閉(3)= 0 chroot("/mnt/foo") = 0 chdir ("/") = 0 execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (沒有那個文件或目錄) open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/lib/charset.alias", O_RDONLY|O_NOFOLLOW) = -1 ENOENT (沒有這樣的文件或目錄) 寫(2,“chroot:”,8chroot:)= 8 write(2, "執行命令失敗 \342\200\230/bin/ls"..., 35 執行命令失敗 '/bin/ls') = 35 open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (沒有這樣的文件或目錄) open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (沒有那個文件或目錄) write(2, ": 沒有這樣的文件或目錄", 27: 沒有這樣的文件或目錄) = 27 寫(2,“\n”,1 ) = 1 關閉(1)= 0 關閉(2)= 0 退出組(127)=? +++ 退出 127 +++
那麼,這是否
ENOENT
具有誤導性?是的 - ENOENT 有點誤導。對我來說,它一直意味著“找不到文件”。
當找不到動態連結器時,execve() 獲取 ENOENT。
當引導核心嘗試載入
init
(或 linuxrc 或其他)時,我得到的錯誤是“ Failed to execute /linuxrc (error -2). Attempting defaults… ”。問題的發生是由於我的腳本中的一個錯誤創建了這個初始 ramdisk。(它省略了“=>” by 未指出的庫
ldd
)。兩個額外的問題需要思考以獲得額外的學分:
- 什麼是沒有路徑
linux-vdso.so.1
的顯示?ldd
- 為什麼
ldd
顯示 ld-linux.so 沒有“=>
”?
問題
/bin/ls
不只是需要您提供的共享庫。它還需要載入它們的程序;linux載入器。要解決您的問題,您可以將載入程序從您的系統(通常
/lib/ld-linux.so.2
)複製到您的 chroot(/mnt/foo/lib/ld-linux.so.2
)的位置。