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 루트 루트 5212 7월 23일 09:35 /mnt/foo/etc/ld.so.cache
-rw-r--r-- 1 루트 루트 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 root256224 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}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). 기본값을 사용해 보세요...".

이 초기 램디스크를 생성하는 스크립트의 오류로 인해 문제가 발생합니다. ("=>"로 표시되지 않은 라이브러리는 생략됩니다 ldd).

추가 학점을 얻으려면 고려해야 할 두 가지 추가 질문이 있습니다.

  • 경로가 없으면 무엇을 보여주나요 linux-vdso.so.1?ldd
  • ld-linux.so가 표시될 때 왜 ldd" "가 없나요 =>?

답변1

문제는 /bin/ls제공하는 공유 라이브러리 이상의 것이 필요하다는 것입니다. 또한 이를 로드하려면 프로그램이 필요합니다. Linux 로더.

문제를 해결하려면 시스템(보통 /lib/ld-linux.so.2)에서 chroot() 위치로 로더를 복사하면 됩니다 /mnt/foo/lib/ld-linux.so.2.

관련 정보