Linux

為什麼 chroot 在現有文件上獲得 ENOENT?

  • July 23, 2014

;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. A stringson/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)的位置。

引用自:https://unix.stackexchange.com/questions/146059