diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-02-15 03:12:28 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-02-15 03:13:15 +0900 |
| commit | 72b0160aadac590bc479b9ec86e0378a95d2bdc0 (patch) | |
| tree | 6dc823776b40ef448e1ea6c073493cb426a84796 /helper/bwrap/sequential.go | |
| parent | ea8d1c07df18ceb94932fcc94ad00eb57c99da33 (diff) | |
helper/bwrap: implement file copy flags
These are significantly more efficient and less error-prone than mounting an external tmpfile. This should also reduce attack surface as the resulting files are private to its specific sandbox.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper/bwrap/sequential.go')
| -rw-r--r-- | helper/bwrap/sequential.go | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/helper/bwrap/sequential.go b/helper/bwrap/sequential.go index fb97e651..53ab8aae 100644 --- a/helper/bwrap/sequential.go +++ b/helper/bwrap/sequential.go @@ -2,14 +2,19 @@ package bwrap import ( "encoding/gob" + "fmt" + "io" "os" "strconv" + + "git.gensokyo.uk/security/fortify/helper/proc" ) func init() { gob.Register(new(PermConfig[SymlinkConfig])) gob.Register(new(PermConfig[*TmpfsConfig])) gob.Register(new(OverlayConfig)) + gob.Register(new(DataConfig)) } type PositionalArg int @@ -44,6 +49,10 @@ const ( SyncFd Seccomp + + File + BindData + ROBindData ) var positionalArgs = [...]string{ @@ -74,6 +83,10 @@ var positionalArgs = [...]string{ SyncFd: "--sync-fd", Seccomp: "--seccomp", + + File: "--file", + BindData: "--bind-data", + ROBindData: "--ro-bind-data", } type PermConfig[T FSBuilder] struct { @@ -202,12 +215,59 @@ func (s SymlinkConfig) Append(args *[]string) { *args = append(*args, Symlink.St type ChmodConfig map[string]os.FileMode -func (c ChmodConfig) Len() int { - return len(c) -} - +func (c ChmodConfig) Len() int { return len(c) } func (c ChmodConfig) Append(args *[]string) { for path, mode := range c { *args = append(*args, Chmod.String(), strconv.FormatInt(int64(mode), 8), path) } } + +const ( + DataWrite = iota + DataBind + DataROBind +) + +type DataConfig struct { + Dest string `json:"dest"` + Data []byte `json:"data,omitempty"` + Type int `json:"type"` + proc.File +} + +func (d *DataConfig) Path() string { return d.Dest } +func (d *DataConfig) Len() int { + if d == nil || d.Data == nil { + return 0 + } + return 3 +} +func (d *DataConfig) Init(fd uintptr, v **os.File) uintptr { + if d.File != nil { + panic("file initialised twice") + } + d.File = proc.NewWriterTo(d) + return d.File.Init(fd, v) +} +func (d *DataConfig) WriteTo(w io.Writer) (int64, error) { + n, err := w.Write(d.Data) + return int64(n), err +} +func (d *DataConfig) Append(args *[]string) { + if d == nil || d.Data == nil { + return + } + var a PositionalArg + switch d.Type { + case DataWrite: + a = File + case DataBind: + a = BindData + case DataROBind: + a = ROBindData + default: + panic(fmt.Sprintf("invalid type %d", a)) + } + + *args = append(*args, a.String(), strconv.Itoa(int(d.Fd())), d.Dest) +} |
