루트 권한을 요구하지 않고 잠재적으로 위험한 프로세스를 격리하고 싶습니다. 그러나 시스템 호출 pivot_root
은 EINVAL
.
struct clone_args ca = {
.flags = CLONE_NEWUSER | CLONE_NEWNS,
};
pid = syscall(SYS_clone3, &ca, sizeof ca);
if (pid == 0) {
mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL);
mount(".", ".", NULL, MS_BIND | MS_REC, NULL);
mkdir("./oldroot", 0777);
syscall(SYS_pivot_root, ".", "./oldroot"); // Fails with EINVAL
}
printk
커널에 호출을 추가하고 다시 컴파일했는데 이 검사에서 실패했다는 것을 알았습니다 .if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
.
무슨 뜻이에요 MNT_LOCKED
? new_mnt
이 플래그를 갖지 않으 려면 어떻게 해야 합니까 ? 일반 사용자로서 사용자 네임스페이스에서 이 작업을 수행할 수 있습니까?
답변1
pivot_root
Linux 커널 소스 코드에 대한 나의 해석은 대상이 상주하는 사용자 네임스페이스에서 대상을 설치해야 한다는 것입니다 .
MNT_LOCKED
에 의해 주로 설정되는 것으로 보이며 lock_mnt_tree
, 마운트 네임스페이스가 변경되는 여러 곳에서 호출되며, 등의 설정에 의해 사용된다 if (child->mnt_parent->mnt_ns->user_ns != user_ns)
.
의견에서는 lock_mnt_tree
이는 사용자 네임스페이스의 프로세스가 마운트를 마운트 해제하고 가려진 콘텐츠를 보는 것을 방지하기 위해 수행된다고 말합니다. 중요한 디렉토리 위에 있는 빈 디렉토리에 마운트를 바인딩하는 것은 컨테이너가 액세스하지 못하도록 하는 일반적인 방법이기 때문입니다.
사용자 네임스페이스 공유를 해제하기 위해 피벗 이후까지 기다리면 이 문제가 해결될 수 있다고 생각합니다. 사용자 네임스페이스가 마운트 네임스페이스의 "소유자"가 되도록 사용자 네임스페이스 공유를 해제할 때/후에 마운트 네임스페이스를 다시 공유 해제하는 것을 잊지 마십시오.