aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/bwrap/sequential.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-15 03:12:28 +0900
committerOphestra <cat@gensokyo.uk>2025-02-15 03:13:15 +0900
commit72b0160aadac590bc479b9ec86e0378a95d2bdc0 (patch)
tree6dc823776b40ef448e1ea6c073493cb426a84796 /helper/bwrap/sequential.go
parentea8d1c07df18ceb94932fcc94ad00eb57c99da33 (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.go68
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)
+}