커널 공간에서 파일 권한/액세스 결정은 언제(그리고 어떻게) 이루어 집니까?

커널 공간에서 파일 권한/액세스 결정은 언제(그리고 어떻게) 이루어 집니까?

나는 Linux 권한이 작동하는 방식(기존 Unix DAC 권한 및 표시 방식, 프로세스 관련 보안 컨텍스트(예: 자격 증명 구조, 기능 등), LSM 후크 등)에 대해 상대적으로 잘 이해하고 있습니다. (E)UID/E(GID) 등에 대한 링크 내가 이해하지 못하고 커널 코드에서 찾기 어려운 점은 ftrace(pass trace-cmd)를 사용하여 이러한 검사가 실제로 커널 공간에서 (아마도) 수행되는 때입니다.어느 지점실제로 액세스 결정이 내려집니다.

상세 설명:

/dir루트 chmod가 소유한 디렉토리가 있습니다 r-x------(500). 권한이 없는 사용자로서 실행했는데 /bin/ls /dir예상대로 권한 거부 오류가 발생했습니다.

실행하면 사용자 공간으로 돌아가서 (예: "Permission Denied") 로 설정된 시스템 호출을 strace -s 10000 /bin/ls /dir볼 수 있습니다 . 그런 다음 STDERR에 오류 메시지를 인쇄하는 후속 시스템 호출이 있으며 모든 것이 예상대로 작동합니다. 나는 여기서 시스템 호출을 보거나 호출한 적이 없습니다.open-1errnoEACCESwritegetdentsgetdents64

별도의 터미널 탭(바이너리가 실행될 때 트리거됨)에서trace-cmd record -p function_graph -F /bin/ls 권한이 없는 동일한 사용자로 Trace-cmd를 사용하여 동일한 테스트를 실행하면 기본적으로 내가 보는 대부분의 시스템 호출을 일대일로 매핑할 수 있습니다. strace 및 Trace-cmd 출력./bin/ls /dirtrace-cmdls

그러나 차이점은 open시스템 호출 후의 Trace-cmd 출력에서 ​​쓰기 출력과 해당 종료를 보는 대신 getdents호출이 수행되는 것을 본다는 것입니다(및 반복된 디렉토리에 있는 항목의 전체 호출 트리 등). . . 내 생각에는 ftrace의 제한(및 내 이해로 인한 제한 가능성)으로 인해 출력에서 ​​시스템 호출 인수나 반환을 볼 수 없으므로 권한 오류가 언제 발생하는지 알 수 없습니다. 그러나 내 제한된 이해에 따르면 커널은 실제로 전체 디렉토리 목록을 수행하지만 출력을 사용자 공간으로 반환하지 않는 것 같습니다.

그렇다면 실제로 무슨 일이 일어나고 있는지 설명할 수 있는 사람이 있습니까? trace-cmd커널이 실제로 getdents시스템 호출을 실행하고 있지만 strace열기 호출이 실패한 후 종료되는 이유는 무엇입니까? 권한 관련 문제를 다루는 대부분의 포럼 게시물(여기 및 다른 곳)에서는 파일을 열 때 확인할 것을 제안하지만 자세한 내용은 제공하지 않습니다. 비록 이것이 내가 본 것과 일치하지만 strace(그러나 ftrace/ 는 아님 trace-cmd).

커널 소스를 보고 open/ systemcalls에서 openat수동으로 추적하면 inode_permission -> do_inode_permission -> generic_permission -> acl_permission_check후자가 실제로 클래식 Unix 권한을 비교하고 그로부터 반환되는 것과 같은 일련의 함수 호출을 볼 수 있습니다. 또한 SELinux, Apparmor, SMACK, Tomoyo 등과 같은 다른 곳에서도 LSM에 대한 후크를 볼 수 있으며 이들이 작동할 것이라고 상상합니다.

내 가정은 디렉토리를 열려고 할 때 권한 확인이 발생하고 커널이 아니오라고 말하고 사용자 공간에 오류가 반환되며 실제로 디렉토리 목록을 수행하는 지점에 도달하지 못한다는 것입니다. 그러나 출력에 따르면 trace-cmd디렉토리 목록이 실제로 발생하는 것처럼 보이지만 더 이상 확실하지 않습니다.

가능한 한 기술적으로 깊이 있는 정보를 제공해 주시면 대단히 감사하겠습니다. 또한 Systemtap을 사용하면 더 많은 정보를 얻을 수 있다는 것을 알고 있지만 이에 대해 내가 아는 것은매우제한된!

인지도를 높이기 위해 Debian 기반 배포판에서 커널 버전 2.6.35 및 6.5.0을 테스트했는데 결과는 비교적 비슷했습니다.

답변1

사용자 오류와 이해 부족 trace-cmd(특히 -F내가 사용하는 플래그)이 문제입니다.

내 가정은 실행 중에 "ls" 프로세스가 실행되는 것을 볼 때까지 기다렸다가 연결한다는 것 trace-cmd record -p function_graph -F /bin/ls입니다 . trace-cmd이로 인해 -F바이너리가 거기에 있게 된 다음 실행됩니다(루트 trace-cmd로 실행된다는 점을 고려하면 루트로). 해키적인 해결 방법은 내가 프로세스에 연결되었는지 확인하는 것이었습니다. 일부 추악한 C는 프로세스의 PID를 얻는 동안 몇 초 동안 잠자기 상태를 유지한 다음 프로세스가 ls사용자로 실행되도록 했습니다. 이렇게 하면 모든 것이 예상됩니다. 제가 원래 이해한 내용이 정확하다는 것을 확인할 수 있었습니다.

open참고로 권한 검사는 시스템 호출의 함수 호출 체인을 따라 파일을 열 때 수행됩니다 . 일부 코드는 처음에 빈 파일 설명을 할당하고 구조의 비트를 채우기 시작합니다. 실제 권한 확인은 호출 체인의 끝 부분에서 발생하는 것 같습니다. 디렉터리 개체인 경우 실행 권한을 확인하기 위한 전용 코드가 있는데, 이는 해당 비트가 다르게 동작하기 때문에 의미가 있습니다. 그런 다음 기본 DAC 검사를 수행하는 함수 may_open를 호출합니다. 여기에도 LSM 검사가 있습니다. 이것이 실패하면 예상대로 권한 오류가 반환됩니다.inode_permissiongeneric_permission

관련 정보