You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

以root运行Golang代码时出现Fork/exec /bin/sh权限拒绝问题

问题原因

当以root运行时,你先调用os.Setuid(1000)切换到普通用户,此时进程失去了创建CLONE_NEWUSER用户命名空间所需的CAP_SYS_ADMIN权限,导致后续执行/bin/sh时触发权限错误。而以uid1000运行时,Manjaro默认允许普通用户创建用户命名空间,因此可以正常执行。

修复后的代码
package main

import (
    "fmt"
    "os"
    "os/exec"
    "syscall"
)

func main() {
    cmd := exec.Command("/bin/sh")

    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    cmd.Env = []string{"PS1=-[ns-process]- # "}
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWNS |
            syscall.CLONE_NEWUTS |
            syscall.CLONE_NEWIPC |
            syscall.CLONE_NEWPID |
            syscall.CLONE_NEWNET |
            syscall.CLONE_NEWUSER,
        UidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      1000,
                Size:        1,
            },
        },
        GidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      1000,
                Size:        1,
            },
        },
    }

    if err := cmd.Run(); err != nil {
        fmt.Printf("Error running the /bin/sh command - %s\n", err)
        os.Exit(1)
    }
}
关键修改说明
  • 移除os.Setuid(1000)调用:保留root权限以满足创建CLONE_NEWUSER命名空间的权限要求。
  • 修改Uid/Gid映射的HostID为1000:让新命名空间内的root用户(ContainerID 0)直接映射到宿主机的1000用户/组,这样新启动的/bin/sh在命名空间内拥有root权限,但在宿主机层面以普通用户身份运行,兼顾权限需求与安全性。

内容的提问来源于stack exchange,提问作者stackflow-crystal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:06:27