ルート権限を必要とせずに潜在的に危険なプロセスを分離したいと思います。しかし、システムコール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
これはユーザーの名前空間のプロセスがマウントをアンマウントし、隠されたコンテンツを見るのを防ぐために行われると言います。重要なディレクトリの上にある空のディレクトリにマウントをバインドすることは、コンテナがアクセスできないようにする一般的な方法です。
ユーザーの名前空間の共有を解除するためにピボットを待つことでこの問題を解決できると思います。ユーザーネームスペースがマウントネームスペースの「所有者」になるように、ユーザーネームスペースの共有を解除するとき/後にマウントネームスペースを再共有解除することを忘れないでください。