Exit from a chroot with Golang

Lately I needed to chroot into a directory, do some work and then exit from it using Golang, but I could only find an example for Python online.

So here comes its Go equivalent! I decided to make a helper function for this:

import (
    "os"
    "syscall"
)

func Chroot(path string) (func() error, error) {
    root, err := os.Open("/")
    if err != nil {
        return nil, err
    }

    if err := syscall.Chroot(path); err != nil {
        root.Close()
        return nil, err
    }

    return func() error {
        defer root.Close()
        if err := root.Chdir(); err != nil {
            return err
        }
        return syscall.Chroot(".")
    }, nil
}

Here we’re opening the real root first, just to keep a file descriptor around. Then once we have chrooted we’ll still be able to call root.Chdir(), which will trigger fchdir(2) behind the scene.

Here is an example on how to use that helper function :

package main
 
func main() {
    exit, err := Chroot("/path/to/dir")
    if err != nil {
        panic(err)
    }
 
    // do some work
    //...
 
    // exit from the chroot
    if err := exit(); err != nil {
        panic(err)
    }
}

Please note that chroot(2) does not change the current working directory, so depending on your needs you might want to call os.Chdir(“/”) after you chrooted.

comments powered by Disqus