![마운트 네임스페이스에서 Pivot_root(".", ".")의 이상한 동작](https://rvso.com/image/168809/%EB%A7%88%EC%9A%B4%ED%8A%B8%20%EB%84%A4%EC%9E%84%EC%8A%A4%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%97%90%EC%84%9C%20Pivot_root(%22.%22%2C%20%22.%22)%EC%9D%98%20%EC%9D%B4%EC%83%81%ED%95%9C%20%EB%8F%99%EC%9E%91.png)
나는 컨테이너를 이해하려고 노력하고 있는데 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/..
containerfs
bindmountpoint
마찬가지로 시도하면 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
진짜 버그 같은데...
배포판의 최신 커널을 확인하고 자세한 내용을 보고해 주세요(테스트 프로그램을 첨부하세요!).