mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
36 lines
980 B
Go
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
|
|
}
|