%EC%97%90%20%EA%B3%84%EC%86%8D%20%EC%95%A1%EC%84%B8%EC%8A%A4%ED%95%A0%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
프로그램이 열린 파일 설명자를 상속하거나 전달하는 것이 가능합니다. 그렇지 않으면 파일의 읽기(또는 쓰기)가 허용되지 않습니다. 예를 들어:
(sudo -u nobody echo "hello world") > ~/test-file
(sudo -u nobody cat) < ~/test-file
질문: 사용자가 액세스할 수 없는 현재 디렉터리(또는 루트 디렉터리)를 상속받은 경우 해당 디렉터리에 액세스할 수 있습니까?
답변1
파일 설명자와의 비교는 매우 오해의 소지가 있습니다. 프로세스의 현재 및 루트 디렉토리는 파일 설명자나 "열린 파일 설명"(a struct file
)에 대한 포인터가 아니라 단지 디렉토리 항목( struct dentry
s)에 대한 포인터입니다.
커널은 모든 종류의 핸들을 통해 하위 프로세스에 의해 상속될 수 있는 현재 또는 루트 디렉토리가 가리키는 디렉토리 inode를 참조하는 열린 파일 설명을 유지하지 않습니다.
어떤 방식으로든 사용하려면 다른 파일과 마찬가지로 현재 디렉터리와 루트 디렉터리를 경로별로 열어야 하며 모든 표준 검사가 적용됩니다.
파일을 열면 O_PATH
불투명한 핸들만 반환되고 다음과 같이 성공합니다.어느일반적으로 읽기 또는 쓰기를 위해 열 수 없는 파일(해당 경로에 액세스할 수 있는 경우):
$ perl -e 'sysopen my $fh, "/root", 0, 0 or die "$!"'
Permission denied at -e line 1.
$ perl -e 'sysopen my $fh, "/root", 010000000, 0 or die "$!"' # 010000000 is O_PATH
$
이러한 불투명한 fd는 권한이 있는 프로세스에서도 일반 fd로 사용할 수 없으며 다행히도 이를 일반 파일 설명자에 넣기 openat(fd, "", AT_EMPTY_PATH|O_RDWR)
위해 수행할 수 있는 방법이 없습니다 ;-)dup()
답변2
아니요.
# sudo -u nobody ls .
ls: cannot access '.': Permission denied
# sudo -u nobody ls -d .
ls: cannot access '.': Permission denied
# chmod o-rwx /chroot
# chroot --userspec=nobody:nobody /chroot
chroot: failed to run command ‘/bin/bash’: Permission denied
현재 디렉터리(또는 루트 디렉터리)에 대한 쓰기 액세스의 경우에도 마찬가지입니다. 그렇지 않은 경우 보안 버그의 원인이 될 수 있습니다. :-).
O_PATH
Linux에서 열린 파일 설명자에도 비슷한 동작이 적용됩니다 .
POSIX( 정의하지 않음 O_PATH
)는 openat(fd, path, ...)
유사한 기능이 열린 디렉토리에 대한 액세스 권한을 다시 확인한다는 것을 의미합니다 fd
.~하지 않는 한 fd
로 열렸습니다 O_SEARCH
. 리눅스는 지원하지 않습니다O_SEARCH
.