drnbotxo449747 2016-03-12 19:17
浏览 160
已采纳

有没有办法去chroot / sandbox进行os.exec调用(防止rm -rf /)

I want to test/automate some repositories, the basic flow is something like:

repos := []string{"repo 1", "repo 2", ...}
for r := range repos {
    // git clone the repo 
    // cd repo dir
    // make test
    // make build
    // ...
}

I am doing this with GO using os.exec to call the all the series of commands, something like:

 exec.Command("sh", "-c", "git clone project")

So far so good, but I would like to know if there is a way to secure/protect against something miswriting on the Makefile that could be doing something like rm -rf /. and break my host.

Basically I would like to use the system libraries/tools but restrict/chroot only the output to a specific workdir, so that I can avoid pre-build a chroot for this.

A working solution is to use a FreeBSD jail, but I would like to know if there an alternative/secure way of doing this without the need of containers,virtualbox,etc; and using a basic Mac OS X workstation. so that anyone could "safely" run & test without worries.

Any ideas ?

  • 写回答

1条回答 默认 最新

  • doukuanyong1939 2016-03-14 08:25
    关注

    You should be fine using os.Setuid/os.Setgid (example.go):

    package main
    
    import (
        "log"
        "flag"
        "os"
        "os/exec"
        "syscall"
    )
    
    func main() {
        var oUid = flag.Int("uid", 0, "Run with User ID")
        var oGid = flag.Int("gid", 0, "Run with Group ID")
        flag.Parse()
    
        // Get UID/GUID from args
        var uid = *oUid
        var gid = *oGid
    
        // Run whoami
        out, err := exec.Command("whoami").Output()
        if err != nil {
            log.Fatal(err)
            return
        }
    
        // Output whoami
        log.Println("Original UID/GID whoami:", string(out))
        log.Println("Setting UID/GUID")
    
        // Change privileges
        err = syscall.Setgid(gid)
        if err != nil {
            log.Println("Cannot setgid")
            log.Fatal(err)
            return
        }
    
        err = syscall.Setuid(uid)
        if err != nil {
            log.Println("Cannot setuid")
            log.Fatal(err)
            return
        }
    
        // Execute whoami again
        out, err = exec.Command("whoami").Output()
        if err != nil {
            log.Fatal(err)
            return
        }
        log.Println("Changed UID/GID whoami:", string(out))
    
    
        // Do some dangerous stuff
        log.Println("Creating a executable file within /bin should fail...")
        _, err = os.Create("/bin/should-fail")
        if err == nil {
            log.Println("Warning: operation did not fail")
            return
        }
    
        log.Println("We are fine", err)
    }
    

    I would also recommend to read about setting gid/uid properly (https://unix.stackexchange.com/questions/166817/using-the-setuid-bit-properly, in C). Oh! its needed to set gid before uid, because the example fails if you don't do so.

    You should execute example.go with root privileges and specify unprivileged gid/uid to the command with flags -gid,-uid respectively.

    sudo go run example.go -uid <unprivileged id> -gid <unprivileged id>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)