마운트 네임스페이스에서 Pivot_root(".", ".")의 이상한 동작

마운트 네임스페이스에서 Pivot_root(".", ".")의 이상한 동작

나는 컨테이너를 이해하려고 노력하고 있는데 LXC 개발자가 발견한 트릭을 우연히 발견했습니다.이 runc PRpivot_root(".", "."): 이전 루트를 넣을 디렉터리가 필요하지 않도록 호출할 수 있습니다 . 그러나 이로 인해 마운트 네임스페이스가 이상하게 작동하게 됩니다.

unshare --user --map-root-user --mount bash -c "
mount --bind containerfs bindmountpoint
cd bindmountpoint
pivot_root . .
# this is fine:
ls -l /
# this is not fine:
ls -l /..
"

의 부모는 또는 루트 마운트 네임스페이스의 루트를 가리키는 또는 를 .통해 액세스됩니다 (아직 중첩을 시도하지 않았습니다)! 이는 nor 의 상위 항목을 가리키는 것이 아니라 실제로는 루트/외부 마운트 네임스페이스의 루트를 가리킵니다../../../proc/<any>/cwd/..containerfsbindmountpoint

마찬가지로 시도하면 nsenter --user --preserve-credentials --mount --target=<pid>이 새 프로세스의 CWD가 루트 마운트 네임스페이스의 루트에 배치됩니다.

내가 pivot_root(".", "oldroot"). 파일 설명자 umount -l /또는 umount -l /proc/1/cwd.

나는 또한 사용자 정의 C 프로그램에서 이 일련의 syscall을 시도했습니다. 왜냐하면 의 문서는 pivot_root현재 프로세스에 대한 보증을 제공하기 때문입니다(그래서 나는 모든 것을 동일한 프로세스에서 수행합니다). 동작은 위에 표시된 CLI 도구를 사용하는 다중 프로세스 단계와 동일합니다.

5.3 커널에서 테스트되었습니다.

내가 달릴 때 무슨 일이 벌어지고 있는 걸까 pivot_root(".", ".")?

답변1

pivot_root(new_root, put_old)호출 프로세스의 이전 루트 디렉터리(마운트의 루트여야 함)를 로 이동 하고 그 위치에 put_old놓습니다 . new_root그런 다음 현재 디렉터리와 이전 루트 디렉터리로 설정되었던 모든 프로세스의 루트를 new_root.

따라서 새 루트 디렉터리 뒤에는 pivot_root(".", ".")이전 루트 디렉터리가 그 위에 마운트됩니다.

다른 디렉토리가 마운트된 디렉토리로 해석될 때마다 ..실제로는 맨 위에 마운트된 디렉토리로 해석됩니다. 이는 ..파일 시스템의 루트 디렉터리를 제외하고 경로 탐색 시 특별한 처리가 없고 디스크에 저장된 디렉터리 항목으로 구현된 역사적인 Unix 및 Linux 동작과 일치합니다 .

이는 마운트 네임스페이스 이스케이프가 아닙니다.

답변2

진짜 버그 같은데...

배포판의 최신 커널을 확인하고 자세한 내용을 보고해 주세요(테스트 프로그램을 첨부하세요!).

관련 정보