프로그램은 열린 파일 설명자를 상속하거나 전달할 수 있습니다. 그렇지 않으면 파일을 읽거나 쓸 수 없습니다. 예를 들어:
(sudo -u nobody echo "hello world") > ~/test-file
(sudo -u nobody cat) < ~/test-file
질문: 사용자가 액세스할 수 없는 현재 디렉터리(또는 루트 디렉터리)를 상속받은 경우 해당 디렉터리에 액세스할 수 있습니까?
답변1
파일 설명자와의 비교는 매우 잘못된 것입니다. 프로세스의 현재 및 루트 디렉터리는 파일 설명자나 "열린 파일 설명"(a)에 대한 포인터가 아니라 디렉터리 항목(들)에 대한 포인터 struct file
일 뿐입니다 .struct dentry
커널은 현재 디렉터리나 루트 디렉터리가 가리키는 디렉터리 inode를 참조하는 열린 파일 설명을 유지하지 않으며 하위 프로세스는 모든 유형의 핸들을 통해 디렉터리 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
$
openat(fd, "", AT_EMPTY_PATH|O_RDWR)
권한 있는 프로세스의 경우에도 이러한 불투명 fd는 일반 fd로 사용할 수 없습니다. 다행히도 이를 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
현재 디렉터리(또는 루트 디렉터리)에 대한 쓰기 액세스도 마찬가지입니다. 그렇지 않다면 이것이 보안 버그의 원인이 될 것이라고 생각합니다 :-).
Linux에서 열린 파일 설명자에도 비슷한 동작이 적용됩니다 O_PATH
.
POSIX (정의되지 않음 O_PATH
)은 openat(fd, path, ...)
유사한 기능이 열린 디렉토리에 액세스하기 위한 권한을 다시 확인한다는 것을 의미합니다 fd
.~하지 않는 한 fd
으로 열립니다 O_SEARCH
. Linux에서는 지원되지 않습니다.O_SEARCH
.