web-dev-qa-db-ja.com

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

; TL-DR --回答:ダイナミックリンカーld-linux-x86-64.so.2が欠落していたため。

-ro,loopにsquashfs(問題ではない)ファイルシステム/mnt/fooをマウントしました。

特に次のものが含まれています(/mnt/fooはマウントポイントです)。

-rwxr-xr-x1ルートルート110088 2013年1月17日/mnt/foo/bin/ls
-rw-r--r--1ルートルート5212年7月2309:35/mnt/foo/etc/ld.so.cache 
-rw-r--r--1ルートルート57月23日09:35/mnt/foo/etc/ld.so.conf 
 -rw-r--r--1ルートルート31168maj 23 2013 /mnt/foo/lib/libacl.so.1
-rw-r--r--1ルートルート18624maj 20 2013 /mnt/foo/lib/libattr.so.1
-rwxr-xr-x1ルートルート1853400okt 12 2013/mnt/foo/lib/libc.so.6
-rw- r--r--1ルートルート14664okt 12 2013/mnt/foo/lib/libdl.so.2
-rw-r--r--1ルートルート256224 2013年3月11日/ mnt/foo /lib/libpcre.so.3
-rwxr-xr-x1ルートルート135757okt 12 2013/mnt/foo/lib/libpthread.so.0
-rw-r--r --1ルートルート31760okt 12 2013/mnt/foo/lib/librt.so.1
-rw-r--r--1ルートルート134224maj 23 2013/mnt/foo/lib/libselinux .so.1 

/mnt/foo/etc/ld.so.confには、/libだけが含まれる単一の行(改行を含む)が含まれます。

ファイルシステムを作成する前に、ldconfig -r ${TOPDIR}を実行しました。${TOPDIR}は、現在/mnt/fooにマウントされている場所に解決されました。 /mnt/foo/etc/ld.so.cachestringsは、/lib/libpcre.so.3などの文字列が含まれていることを示しているため、共有ライブラリの問題ではないと思います。

見落としているのはばかげているに違いないと思いますが、単純なchroot /mnt/foo /bin/lsが機能しない理由がわかりません。

readelf -d /mnt/foo/bin/ls | grep NEEDEDは、必要に応じてこれらのライブラリを表示します。

 0x0000000000000001(NEEDED)共有ライブラリ:[libselinux.so.1] 
 0x0000000000000001(NEEDED)共有ライブラリ:[librt.so.1] 
 0x0000000000000001(NEEDED)共有ライブラリ: [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 
 close(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 
 read(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、MAP_NO -1、0)= 0x7fc1158a3000 
 close(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(0x7fc11589d_、16 ____。] 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 
 close(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 
 write(2、 "\ n"、1 
)= 1 
 close(1)= 0 
 close(2) = 0 
 exit_group(127)=?
 +++は127 +++ 
で終了しました

それで、これはENOENT誤解を招くのでしょうか?

YES --ENOENTは少し誤解を招く恐れがあります。私にとっては常に「ファイルが見つかりません」という意味でした。

ダイナミックリンカが見つからない場合、execve()はENOENTを取得します。

起動カーネルがinit(またはlinuxrcなど)を読み込もうとすると、エラーは「/ linuxrcの実行に失敗しました(エラー-2)。デフォルトを試行しています... "」です。 。

この問題は、この初期ramdiskを作成したスクリプトのバグが原因で発生しました。 (lddによって「=>」で示されていないライブラリは省略されています)。

追加のクレジットについて熟考するための2つのボーナス質問:

  • lddがパスなしで表示するlinux-vdso.so.1とは何ですか?
  • lddが "=>"なしでld-linux.soを表示するのはなぜですか?
3
MattBianco

問題は /bin/ls提供した共有ライブラリだけが必要なわけではありません。また、それらをロードするプログラムも必要です。 Linuxローダー。

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

3
chaos