항상 존재하는 파일이 있고 '일반적인'사용자가 파일을 지정할 수 없습니까?


14

단위 테스트를 위해 이것이 필요합니다. 매개 변수로 전달 된 파일 경로에서 lstat 를 수행하는 함수가 있습니다. lstat코드 커버리지가 90 %에 도달해야하기 때문에 실패한 코드 경로를 트리거해야합니다.

테스트는 단일 사용자 만 실행할 수 있으므로 우분투에 항상 존재하는 파일이 있는지 궁금하지만 일반 사용자에게는 파일이나 폴더에 대한 읽기 권한이 없습니다. ( lstat루트로 실행하지 않으면 실패합니다.)

존재하지 않는 파일은 해결책이 아닙니다. 왜냐하면 이미 트리거하고있는 별도의 코드 경로가 있기 때문입니다.

편집 : 파일에 대한 읽기 권한 부족만으로는 충분하지 않습니다. 그것으로 lstat여전히 실행될 수 있습니다. / root에 폴더와 그 안에 파일을 만들어서 루트 액세스 권한이있는 로컬 컴퓨터에서 트리거 할 수있었습니다. 폴더에 권한 700을 설정합니다. 그래서 루트로만 액세스 할 수있는 폴더에있는 파일을 찾고 있습니다.


6
이럴/etc/shadow
로미오 Ninov

3
프로그램이 chroot 또는 별도의 네임 스페이스에서 실행될 수 있으므로 파일이 존재한다고 가정 할 수 없습니다. / proc가 마운트되었다고 가정하고 init가 특별한 것이 아니라면 /proc/1/fd/0그렇게해야합니다.
mosvy

1
@mosvy 감사합니다. 내 로컬 컴퓨터에서 작동합니다. 그러면 QA 및 스테이징 풀에서도 시도해 보겠습니다.
웅크 리고 새끼 고양이

2
버리기 파일을 만들고 자신의 읽기 액세스 권한을 제거 할 수있을 때 테스트 코드를 특정 OS 버전에 연결하는 이유는 무엇입니까?
Kilian Foth

4
모의 파일 시스템이 아닌 실제 파일 시스템에 따라 시작되면 실제로 단위 테스트 가 아니라고 주장합니다 .
Toby Speight

답변:


21

최신 Linux 시스템에서는 /proc/1/fdinfo/0(id 1 프로세스의 파일 디스크립터 1 (stdout)에 대한 정보 ( init루트 pid 네임 스페이스에서로 실행 root))을 사용할 수 있어야합니다 .

(일반 사용자로서) 목록을 찾을 수 있습니다.

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

-type f일반 파일로 제한하지 않으려면 제거하십시오 .

/var/cache/ldconfig/aux-cache우분투 시스템 만 고려하면 다른 잠재적 후보입니다. GNU libc와 함께 제공 /var/cache/ldconfig되는 ldconfig명령에 의해서만 루트로 읽기 + 쓰기 + 검색이 가능한 대부분의 GNU 시스템에서 작동합니다 .


1
감사! /proc/1/fdinfo/0Ubuntu 16.04 및 18.04에서 작동 하면 충분합니다.
웅크 리고 새끼 고양이

1
/proc/1/fdinfo/0컨테이너 (예 : Docker 컨테이너)에서 사용 하는 것이 반드시 필요한 것은 아니며 CI의 컨테이너에서 단위 테스트가 실행되는 경우가 종종 있습니다.
Philipp Wendler

@PhilippWendler, 루트 pid 네임 스페이스를 이미 언급 했습니다 . OP는 컨테이너에 대해 묻지 않고 Ubuntu 시스템의 파일 시스템 레이아웃에 있는지 파일에 대해 묻습니다. 컨테이너에는 파일 및 디렉토리 레이아웃이 포함될 수 있으므로 해당 질문에 대답 할 수 없습니다.
Stéphane Chazelas

12

상기 찾고 lstat는 (2) 맨 페이지 당신은 ENOENT 이외의 오류와 함께 실패 할 수있는 경우에 어떤 영감을 얻을 수 있습니다 (파일이 존재하지 않습니다.)

가장 확실한 것은 :

EACCES 검색 권한의 경로 접두사에있는 디렉토리 중 하나에 대한 거부 경로 .

따라서 검색 할 수없는 디렉토리가 필요합니다.

예, 이미 시스템에있는 것을 찾을 수 있습니다 (아마있을 /var/lib/private경우?). 그러나 다음과 같은 방법으로 직접 만들 수도 있습니다.

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

EACCES와 함께 lstat (2) 작업이 실패합니다. (디렉토리에서 모든 권한을 제거하면이를 보장 chmod -x할 수 있습니다. 디렉토리에있는 파일에 액세스하려면 디렉토리에 대한 실행 권한이 필요하므로 그다지 필요하지 않고 실행 권한을 제거하면 충분합니다.)

매뉴얼 페이지를 보면 lstat (2)가 실패하게 만드는 또 다른 창의적인 방법이 있습니다.

ENOTDIR 의 경로 접두어의 구성 요소 경로가 디렉토리가 아니다.

따라서 파일에 액세스하려고하면 /etc/passwd/nonexistent이 오류가 발생합니다.이 오류는 다시 ENOENT와 다르며 ( "No such file or directory") 사용자 요구에 맞을 수 있습니다.

다른 하나는 다음과 같습니다.

ENAMETOOLONG 경로 가 너무 깁니다.

그러나이 이름에 대해 정말로 긴 이름이 필요할 수 있습니다 (일반적으로 4,096 바이트가 제한되지만 시스템 / 파일 시스템에는 더 긴 이름이있을 수 있습니다).

마지막으로, 이것들 중 어느 것이 실제로 당신에게 유용한 지 말하기는 어렵습니다 . "파일이 존재하지 않습니다"시나리오를 트리거하지 않는 것을 원한다고 말합니다. 일반적으로 이는 ENOENT 오류를 의미하지만 실제로는 많은 상위 수준 검사에서 lstat (2)의 오류가 "존재하지 않음"으로 해석됩니다. 예를 들어 쉘 test -e에서 이에 해당 [ -e ...]하는 것은 단순히 위의 모든 것을 "존재하지 않음"으로 해석 할 수 있습니다. 특히 다른 오류 메시지를 리턴하는 좋은 방법이없고 오류를 리턴하지 않으면 파일이 존재한다는 것을 의미하므로, 가장 확실한 경우는 아닙니다.


@StephaneChazelas 그레이트 포인트! 업데이트되었습니다.
filbranden

6

find스스로 할 수 있습니다 .

사용 /etc- 시작 지점으로 구성 파일 디렉토리 :

sudo find /etc -type f -perm 0400 -user root

내 시스템에서 이것은 아무것도 반환하지 않습니다.

당신은 덜 제한적이며 그룹을 허용 할 수 있으며 root(사용자만 root이 그룹의 구성원이어야 함 root) 다음의 권한을 찾으십시오 440.

sudo find /etc -perm 0440 -user root -group root

내 시스템에서 이것은 다음을 반환합니다.

/etc/sudoers.d/README
/etc/sudoers

편집하다:

편집 한 내용에 따라 호출 사용자가 디렉토리 목록을 막을 수있는 권한이없는 디렉토리를 찾고 있습니다.

sudo find / -perm o-rwx -type d -user root -group root 

여기서 나는 -type d다른 사람들을위한 읽기-쓰기-실행 perm 비트가 부족하고 ( o-rwx)이 소유 한 디렉토리 ( )를 찾고 root:root있습니다.

기술적으로, 실행 ( x) 비트가 없으면 디렉토리의 디렉토리 목록 ( lstat(2))을 막을 수 있습니다.

출력 /run/systemd/inaccessible/에서 Systemd init 기반 시스템 에서 찾았 습니다.

파일을에 관해서는 /proc, /sys, /dev:

  • 이러한 파일 시스템은 가상 FS입니다. 즉, 디스크가 아닌 메모리에 있습니다.

  • 에 의존 할 계획이라면 /proc, /proc/1/PID 1 하의 무언가에 의존하십시오. 이후 PID (프로세스)가 존재하지 않기 때문에 신뢰성 / 일관성을 갖기 위해 이후 PID는 아닙니다.


고마워, 나는 내 질문이 틀렸다고 생각한다. 여전히 파일에 대한 읽기 권한없이 파일을 lstat 할 수 있습니다. 폴더에 대한 액세스가 제한되어야합니까? (내가 제목을 수정)
웅크 리고 새끼 고양이

감사. 으로 find / -type d -perm 0400 -user root내가 디렉토리를 발견 /proc/20/map_files/나는 그 폴더 안에 만들어 낸 파일 이름을 참조하는 경우, 같은 /proc/20/map_files/asdasd, 그것은 항상 실패합니다. 해당 폴더가 항상 우분투에 있습니까?
웅크 리고 새끼 고양이

@CrouchingKitten, /proc/1/init가 항상 존재하기 때문에 디렉토리 가 더 안전 할 수 있습니다. 그러나 proc중요한 경우 일반 파일 시스템이 아닙니다.
ilkkachu

감사합니다. 공감대를 주었지만 /proc/1/fdinfo/0현대 우분투 스에서 작동 한다고 보장했기 때문에 다른 대답을 받아 들였습니다 .
웅크 리고 새끼 고양이

-perm o-rwx와 같이 -perm 0비트는 모두 시작됩니다. 여기, 당신은 원할 것 ! -perm -1입니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.