1package core
2
3import (
4 "fmt"
5 "syscall"
6 "unsafe"
7)
8
9const (
10 mfdCloexec = 0x1
11 mfdAllowSealing = 0x2
12 fAddSeals = 0x409 // F_ADD_SEALS
13 fSealSeal = 0x1
14 fSealShrink = 0x2
15 fSealGrow = 0x4
16)
17
18// memfdShm is the production portout.SharedMemAPI backed by memfd_create.
19type memfdShm struct{}
20
21func (memfdShm) NewSharedMem(name string, size int) (int, []byte, error) {
22 if size <= 0 {
23 return -1, nil, fmt.Errorf("memfd: invalid size %d", size)
24 }
25 cname, err := syscall.BytePtrFromString(name)
26 if err != nil {
27 return -1, nil, err
28 }
29 r, _, errno := syscall.Syscall(sysMemfdCreate, uintptr(unsafe.Pointer(cname)), mfdCloexec|mfdAllowSealing, 0)
30 if errno != 0 {
31 return -1, nil, fmt.Errorf("memfd_create: %w", errno)
32 }
33 fd := int(r)
34 if err := syscall.Ftruncate(fd, int64(size)); err != nil {
35 _ = syscall.Close(fd)
36 return -1, nil, fmt.Errorf("memfd ftruncate: %w", err)
37 }
38 if _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), fAddSeals, fSealShrink|fSealGrow|fSealSeal); errno != 0 {
39 _ = syscall.Close(fd)
40 return -1, nil, fmt.Errorf("memfd seal: %w", errno)
41 }
42 data, err := syscall.Mmap(fd, 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
43 if err != nil {
44 _ = syscall.Close(fd)
45 return -1, nil, fmt.Errorf("memfd mmap: %w", err)
46 }
47 return fd, data, nil
48}
49
50func (memfdShm) FreeSharedMem(fd int, data []byte) {
51 if data != nil {
52 _ = syscall.Munmap(data)
53 }
54 if fd >= 0 {
55 _ = syscall.Close(fd)
56 }
57}