2024-10-15 02:15:55 +09:00
|
|
|
package bwrap
|
|
|
|
|
2025-01-22 01:51:10 +09:00
|
|
|
import (
|
|
|
|
"encoding/gob"
|
|
|
|
"os"
|
|
|
|
"slices"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"git.gensokyo.uk/security/fortify/internal/proc"
|
|
|
|
)
|
2024-10-15 02:15:55 +09:00
|
|
|
|
|
|
|
type Builder interface {
|
|
|
|
Len() int
|
|
|
|
Append(args *[]string)
|
|
|
|
}
|
|
|
|
|
|
|
|
type FSBuilder interface {
|
|
|
|
Path() string
|
|
|
|
Builder
|
|
|
|
}
|
|
|
|
|
2025-01-22 01:51:10 +09:00
|
|
|
type FDBuilder interface {
|
|
|
|
Len() int
|
|
|
|
Append(args *[]string, extraFiles *[]*os.File) error
|
|
|
|
}
|
|
|
|
|
2024-10-15 02:15:55 +09:00
|
|
|
func init() {
|
|
|
|
gob.Register(new(pairF))
|
|
|
|
gob.Register(new(stringF))
|
|
|
|
}
|
|
|
|
|
|
|
|
type pairF [3]string
|
|
|
|
|
|
|
|
func (p *pairF) Path() string {
|
|
|
|
return p[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *pairF) Len() int {
|
|
|
|
return len(p) // compiler replaces this with 3
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *pairF) Append(args *[]string) {
|
|
|
|
*args = append(*args, p[0], p[1], p[2])
|
|
|
|
}
|
|
|
|
|
|
|
|
type stringF [2]string
|
|
|
|
|
|
|
|
func (s stringF) Path() string {
|
|
|
|
return s[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s stringF) Len() int {
|
|
|
|
return len(s) // compiler replaces this with 2
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s stringF) Append(args *[]string) {
|
|
|
|
*args = append(*args, s[0], s[1])
|
|
|
|
}
|
|
|
|
|
2025-01-22 01:51:10 +09:00
|
|
|
type fileF struct {
|
|
|
|
name string
|
|
|
|
file *os.File
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fileF) Len() int {
|
|
|
|
if f.file == nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return 2
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fileF) Append(args *[]string, extraFiles *[]*os.File) error {
|
|
|
|
if f.file == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
extraFile(args, extraFiles, f.name, f.file)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func extraFile(args *[]string, extraFiles *[]*os.File, name string, f *os.File) {
|
|
|
|
if f == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
*args = append(*args, name, strconv.Itoa(int(proc.ExtraFileSlice(extraFiles, f))))
|
|
|
|
}
|
|
|
|
|
2024-10-15 02:15:55 +09:00
|
|
|
// Args returns a slice of bwrap args corresponding to c.
|
|
|
|
func (c *Config) Args() (args []string) {
|
|
|
|
builders := []Builder{
|
|
|
|
c.boolArgs(),
|
|
|
|
c.intArgs(),
|
|
|
|
c.stringArgs(),
|
|
|
|
c.pairArgs(),
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy FSBuilder slice to builder slice
|
|
|
|
fb := make([]Builder, len(c.Filesystem)+1)
|
|
|
|
for i, f := range c.Filesystem {
|
|
|
|
fb[i] = f
|
|
|
|
}
|
|
|
|
fb[len(fb)-1] = c.Chmod
|
|
|
|
builders = append(builders, fb...)
|
|
|
|
|
|
|
|
// accumulate arg count
|
|
|
|
argc := 0
|
|
|
|
for _, b := range builders {
|
|
|
|
argc += b.Len()
|
|
|
|
}
|
|
|
|
|
|
|
|
args = make([]string, 0, argc)
|
|
|
|
for _, b := range builders {
|
|
|
|
b.Append(&args)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2025-01-22 01:51:10 +09:00
|
|
|
|
|
|
|
func (c *Config) FDArgs(syncFd *os.File, extraFiles *[]*os.File) (args []string, err error) {
|
|
|
|
builders := []FDBuilder{
|
|
|
|
&seccompBuilder{c},
|
|
|
|
&fileF{positionalArgs[SyncFd], syncFd},
|
|
|
|
}
|
|
|
|
|
|
|
|
argc := 0
|
|
|
|
for _, b := range builders {
|
|
|
|
argc += b.Len()
|
|
|
|
}
|
|
|
|
|
|
|
|
args = make([]string, 0, argc)
|
|
|
|
*extraFiles = slices.Grow(*extraFiles, len(builders))
|
|
|
|
|
|
|
|
for _, b := range builders {
|
|
|
|
if err = b.Append(&args, extraFiles); err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|