go-sandbox/memfd/memfd.go
2019-08-04 17:27:52 -07:00

36 lines
980 B
Go

package memfd
import (
"fmt"
"io"
"os"
"golang.org/x/sys/unix"
)
const roSeal = unix.F_SEAL_SEAL | unix.F_SEAL_SHRINK | unix.F_SEAL_GROW | unix.F_SEAL_WRITE
// DupToMemfd convers a fd to sealed memfd for given name
func DupToMemfd(name string, fin *os.File) (*os.File, error) {
fd, err := unix.MemfdCreate(name, unix.MFD_CLOEXEC|unix.MFD_ALLOW_SEALING)
if err != nil {
return nil, fmt.Errorf("DupToMemfd: memfd_create failed(%v)", err)
}
file := os.NewFile(uintptr(fd), name)
if file == nil {
unix.Close(fd)
return nil, fmt.Errorf("DupToMemfd: memfd new file failed")
}
// TODO: Send file might be more efficient here
if _, err = io.Copy(file, fin); err != nil {
file.Close()
return nil, fmt.Errorf("DupToMemfd: memfd io copy failed(%v)", err)
}
// make memfd readonly
if _, err = unix.FcntlInt(file.Fd(), unix.F_ADD_SEALS, roSeal); err != nil {
file.Close()
return nil, fmt.Errorf("DupToMemfd: memfd seal failed(%v)", err)
}
return file, nil
}