Linuxユーザーの名前空間に_/proc
_をマウントするためにroot以外のユーザーを取得しようとしています。
clone()
を介して名前空間を作成すると、_/proc
_をマウントできます。
ただし、unshare()
を介して名前空間を作成すると、mount()
の呼び出しは_Operation not permitted
_で失敗します。
名前空間がmount()
ではなくclone()
で作成された場合、unshare()
の動作が異なるのはなぜですか。
以下のコードは違いを示しています。
_#define _GNU_SOURCE
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* Space for child's stack */
void try ( const char * msg, int rv ) {
printf ( "%-8s %6d %s\n", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
}
int child ( void * arg ) {
try( "mount_1", mount ( "PROC", "/proc", "proc", 0, NULL ));
try( "umount_1", umount ( "/proc" ));
return 0;
}
int main () {
int clone_flags = 0;
clone_flags |= CLONE_NEWNET;
clone_flags |= CLONE_NEWNS;
clone_flags |= CLONE_NEWPID;
clone_flags |= CLONE_NEWUSER;
try( "clone", clone ( child, child_stack + STACK_SIZE,
clone_flags | SIGCHLD, NULL ));
try( "wait", wait ( NULL ));
try( "unshare", unshare ( clone_flags ));
try( "mount_2", mount ( "PROC", "/proc", "proc", 0, NULL ));
return 0;
}
_
出力:
_clone 31478 Success
mount_1 0 Success
umount_1 0 Success
wait 31478 Success
unshare 0 Success
mount_2 -1 Operation not permitted
_
カーネル_Linux 4.15.0-20-generic
_を使用してUbuntu18.04で実行しています。私は上記のコードを非ルートとして実行しています。
あなたはまだ「間違った」PID名前空間にいると思います。つまり、procfsインスタンスをマウントする権限がありません。
CLONE_NEWPID [...]呼び出しプロセスは新しい名前空間に移動されません。呼び出し元のプロセスによって作成された最初の子は、プロセスID 1を持ち、新しい名前空間でinit(1)の役割を引き受けます。
比較する
CLONE_NEWPID [...] CLONE_NEWPIDが設定されている場合は、新しいPID名前空間にプロセスを作成します。