sandbox: set mkdir perm
All checks were successful
Test / Create distribution (push) Successful in 26s
Test / Fortify (push) Successful in 2m34s
Test / Fpkg (push) Successful in 3m26s
Test / Data race detector (push) Successful in 4m7s
Test / Flake checks (push) Successful in 57s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-03-24 12:45:19 +09:00
parent 0eb1bc6301
commit 40f00d570e
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
4 changed files with 39 additions and 25 deletions

View File

@ -93,7 +93,7 @@ func TestContainer(t *testing.T) {
container. container.
Tmpfs("/tmp", 0, 0755). Tmpfs("/tmp", 0, 0755).
Bind(os.Args[0], os.Args[0], 0). Bind(os.Args[0], os.Args[0], 0).
Mkdir("/usr/bin"). Mkdir("/usr/bin", 0755).
Link(os.Args[0], "/usr/bin/sandbox.test"). Link(os.Args[0], "/usr/bin/sandbox.test").
Place("/etc/hostname", []byte(container.Args[5])) Place("/etc/hostname", []byte(container.Args[5]))
// in case test has cgo enabled // in case test has cgo enabled

View File

@ -101,7 +101,7 @@ func remountWithFlags(n *vfs.MountInfoNode, mf uintptr) error {
func mountTmpfs(fsname, name string, size int, perm os.FileMode) error { func mountTmpfs(fsname, name string, size int, perm os.FileMode) error {
target := toSysroot(name) target := toSysroot(name)
if err := os.MkdirAll(target, perm); err != nil { if err := os.MkdirAll(target, parentPerm(perm)); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())
} }
opt := fmt.Sprintf("mode=%#o", perm) opt := fmt.Sprintf("mode=%#o", perm)
@ -112,3 +112,14 @@ func mountTmpfs(fsname, name string, size int, perm os.FileMode) error {
syscall.MS_NOSUID|syscall.MS_NODEV, opt), syscall.MS_NOSUID|syscall.MS_NODEV, opt),
fmt.Sprintf("cannot mount tmpfs on %q:", name)) fmt.Sprintf("cannot mount tmpfs on %q:", name))
} }
func parentPerm(perm os.FileMode) os.FileMode {
pperm := 0755
if perm&0070 == 0 {
pperm &= ^0050
}
if perm&0007 == 0 {
pperm &= ^0005
}
return os.FileMode(pperm)
}

View File

@ -30,8 +30,8 @@ func toHost(name string) string {
return path.Join(hostPath, name) return path.Join(hostPath, name)
} }
func createFile(name string, perm os.FileMode, content []byte) error { func createFile(name string, perm, pperm os.FileMode, content []byte) error {
if err := os.MkdirAll(path.Dir(name), 0755); err != nil { if err := os.MkdirAll(path.Dir(name), pperm); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())
} }
f, err := os.OpenFile(name, syscall.O_CREAT|syscall.O_EXCL|syscall.O_WRONLY, perm) f, err := os.OpenFile(name, syscall.O_CREAT|syscall.O_EXCL|syscall.O_WRONLY, perm)
@ -47,13 +47,13 @@ func createFile(name string, perm os.FileMode, content []byte) error {
return errors.Join(f.Close(), err) return errors.Join(f.Close(), err)
} }
func ensureFile(name string, perm os.FileMode) error { func ensureFile(name string, perm, pperm os.FileMode) error {
fi, err := os.Stat(name) fi, err := os.Stat(name)
if err != nil { if err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
return err return err
} }
return createFile(name, perm, nil) return createFile(name, perm, pperm, nil)
} }
if mode := fi.Mode(); mode&fs.ModeDir != 0 || mode&fs.ModeSymlink != 0 { if mode := fi.Mode(); mode&fs.ModeDir != 0 || mode&fs.ModeSymlink != 0 {

View File

@ -61,13 +61,16 @@ func (b *BindMount) apply(*Params) error {
source := toHost(b.SourceFinal) source := toHost(b.SourceFinal)
target := toSysroot(b.Target) target := toSysroot(b.Target)
// this perm value emulates bwrap behaviour as it clears bits from 0755 based on
// op->perms which is never set for any bind setup op so always results in 0700
if fi, err := os.Stat(source); err != nil { if fi, err := os.Stat(source); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())
} else if fi.IsDir() { } else if fi.IsDir() {
if err = os.MkdirAll(target, 0755); err != nil { if err = os.MkdirAll(target, 0700); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())
} }
} else if err = ensureFile(target, 0444); err != nil { } else if err = ensureFile(target, 0444, 0700); err != nil {
return err return err
} }
@ -147,7 +150,7 @@ func (d MountDev) apply(params *Params) error {
for _, name := range []string{"null", "zero", "full", "random", "urandom", "tty"} { for _, name := range []string{"null", "zero", "full", "random", "urandom", "tty"} {
targetPath := toSysroot(path.Join(v, name)) targetPath := toSysroot(path.Join(v, name))
if err := ensureFile(targetPath, 0444); err != nil { if err := ensureFile(targetPath, 0444, 0755); err != nil {
return err return err
} }
if err := hostProc.bindMount( if err := hostProc.bindMount(
@ -198,7 +201,7 @@ func (d MountDev) apply(params *Params) error {
uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&buf[0])),
); errno == 0 { ); errno == 0 {
consolePath := toSysroot(path.Join(v, "console")) consolePath := toSysroot(path.Join(v, "console"))
if err := ensureFile(consolePath, 0444); err != nil { if err := ensureFile(consolePath, 0444, 0755); err != nil {
return err return err
} }
if err := hostProc.bindMount( if err := hostProc.bindMount(
@ -313,29 +316,29 @@ func (f *Ops) Link(target, linkName string) *Ops {
func init() { gob.Register(new(Mkdir)) } func init() { gob.Register(new(Mkdir)) }
// Mkdir creates a directory in the container filesystem. // Mkdir creates a directory in the container filesystem.
type Mkdir string type Mkdir struct {
Path string
Perm os.FileMode
}
func (m Mkdir) early(*Params) error { return nil } func (m *Mkdir) early(*Params) error { return nil }
func (m Mkdir) apply(*Params) error { func (m *Mkdir) apply(*Params) error {
v := string(m) if !path.IsAbs(m.Path) {
if !path.IsAbs(v) {
return msg.WrapErr(syscall.EBADE, return msg.WrapErr(syscall.EBADE,
fmt.Sprintf("path %q is not absolute", v)) fmt.Sprintf("path %q is not absolute", m.Path))
} }
target := toSysroot(v) if err := os.MkdirAll(toSysroot(m.Path), m.Perm); err != nil {
if err := os.MkdirAll(target, 0755); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())
} }
return nil return nil
} }
func (m Mkdir) Is(op Op) bool { vm, ok := op.(Mkdir); return ok && m == vm } func (m *Mkdir) Is(op Op) bool { vm, ok := op.(*Mkdir); return ok && m == vm }
func (Mkdir) prefix() string { return "creating" } func (*Mkdir) prefix() string { return "creating" }
func (m Mkdir) String() string { return fmt.Sprintf("directory %q", string(m)) } func (m *Mkdir) String() string { return fmt.Sprintf("directory %q perm %s", m.Path, m.Perm) }
func (f *Ops) Mkdir(dest string) *Ops { func (f *Ops) Mkdir(dest string, perm os.FileMode) *Ops {
*f = append(*f, Mkdir(dest)) *f = append(*f, &Mkdir{dest, perm})
return f return f
} }
@ -368,7 +371,7 @@ func (t *Tmpfile) apply(*Params) error {
} }
target := toSysroot(t.Path) target := toSysroot(t.Path)
if err := ensureFile(target, 0444); err != nil { if err := ensureFile(target, 0444, 0755); err != nil {
return err return err
} else if err = hostProc.bindMount( } else if err = hostProc.bindMount(
tmpPath, tmpPath,