chrootが既存のファイルからENOENTを取得するのはなぜですか?

chrootが既存のファイルからENOENTを取得するのはなぜですか?

;TL-DR-答え:動的リンカー ld-linux-x86-64.so.2 がないからです。

私はすでに-ro,loopそこにいます/mnt/foo

これには以下が含まれます(/mnt/fooマウントポイント)。

-rwxr-xr-x 1 root110088 2013年1月17日/mnt/foo/bin/ls
-rw-r--r-- 1 root root 5212 7月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 root root 31168 maj 23 2013 /mnt/foo/lib/libacl.so.1
-rw-r--r-- 1 root root 18624 maj 20 2013 /mnt/foo/lib/libattr.so.1
-rwxr-xr-x 1 root 1853400 okt 12 2013 /mnt/foo/lib/libc.so.6
-rw-r--r-- 1 root root 14664 okt 12 2013 /mnt/foo/lib/libdl.so.2
-rw-r--r--1 root256224 2013年3月11日/mnt/foo/lib/libpcre.so.3
-rwxr-xr-x 1 root 135757 okt 12 2013 /mnt/foo/lib/libpthread.so.0
-rw-r--r-- 1 root root 31760 okt 12 2013 /mnt/foo/lib/librt.so.1
-rw-r--r-- 1 root root 134224 maj 23 2013 /mnt/foo/lib/libselinux.so.1

/mnt/foo/etc/ld.so.conf1行(改行を含む)を含みます/lib

ファイルシステムを作成する前に、現在インストールされている場所でldconfig -r ${TOPDIR}whereresolvedを実行しました。 onはthisのような文字列が含まれていることを示しているため、共有ライブラリの問題ではないようです。${TOPDIR}/mnt/foostrings/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 (該当するファイルやディレクトリなし)
open("/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 (該当するファイルやディレクトリなし)
open("/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
ムーンマップ(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 (該当するファイルやディレクトリなし)
write(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など)ロードしようとしたときに発生するエラーは、/linuxrcを実行できません(エラー-2)。デフォルトを試してください...」。

この初期RAMディスクを生成するスクリプトのエラーが原因で問題が発生します。 (「=>」とマークされていないライブラリは省略されますldd)。

追加のクレジットを取得するには、考慮する必要がある2つの追加の質問があります。

  • パスがない場合は何を示しますかlinux-vdso.so.1ldd
  • ld-linux.soが表示されたときになぜldd「」はありませんか=>

答え1

問題は、/bin/ls提供する共有ライブラリ以上のものが必要であることです。また、それをロードするにはプログラムが必要です。 Linuxローダー。

問題を解決するには、システム(通常/lib/ld-linux.so.2)からchroot()の場所にローダーをコピーします/mnt/foo/lib/ld-linux.so.2

関連情報