サイズ1でユーザーネームスペースを作成すると機能しますが、サイズが1より大きいと失敗する理由

サイズ1でユーザーネームスペースを作成すると機能しますが、サイズが1より大きいと失敗する理由

私は許可されていないLinuxコンテナを実験しており、ミニマリストコンテナを作成するGoプログラムを作成しています。プログラムは自分自身を分岐し、プロセス内に名前空間を作成します。ただし、何らかの理由でユーザーの名前空間サイズを1より大きく設定すると、通常のユーザーとして実行すると失敗します。

    cmd := exec.Command("/proc/self/exe", "run-container")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags:   syscall.CLONE_NEWUSER | syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
        Unshareflags: syscall.CLONE_NEWNS,
        UidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getuid(),
                Size:        1,   // set this to 2 or more and it fails
            },
        },
        GidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getgid(),
                Size:        1,
            },
        },
    }
    // other flags: CLONE_NEWNET, CLONE_NEWIPC, CLONE_NEWCGROUP, CLONE_NEWUSER,
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    err := cmd.Run()
    if err != nil {
        fmt.Println("ERROR: parent cmd.Run", err)
        os.Exit(1)
    }

上記のコード(およびピボットルートなどの他のすべての項目)は正常に機能します。ただし、Sizeを2に設定すると競合が発生します。

ERROR: parent cmd.Run fork/exec /proc/self/exe: operation not permitted

rootで実行すると機能する機能の問題のようです。

これは私のものです/etc/subuid

lxd:1000:1
root:1000:1
lxd:100000:65536
root:100000:65536
developer:165536:65536
mounter:231072:65536

修正する:

現在のアイテムを他のアイテムにマッピングするにはCAP_SETUIDが必要であることがわかりましたeuid(参照ユーザーネームスペースのマニュアルページ)。

sudo setcap cap_setuid=eip /my/binaryしかし失敗しても。エラーメッセージが次のように変更されました。

ERROR: parent cmd.Run fork/exec /proc/self/exe: permission denied

strace実行すると。EPERM/proc/xx/uid_map

openat(AT_FDCWD, "/proc/25233/uid_map", O_RDWR) = 5
write(5, "0 1000 100\n\0", 12)          = -1 EPERM (Operation not permitted)

関連情報