container/mount: export mount string constants
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m1s
Test / Hakurei (push) Successful in 2m56s
Test / Sandbox (race detector) (push) Successful in 3m47s
Test / Hpkg (push) Successful in 4m1s
Test / Hakurei (race detector) (push) Successful in 4m32s
Test / Flake checks (push) Successful in 1m19s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m1s
Test / Hakurei (push) Successful in 2m56s
Test / Sandbox (race detector) (push) Successful in 3m47s
Test / Hpkg (push) Successful in 4m1s
Test / Hakurei (race detector) (push) Successful in 4m32s
Test / Flake checks (push) Successful in 1m19s
This improves code readability and should also be useful for callers choosing to preserve CAP_SYS_ADMIN. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
b32b1975a8
commit
0f78864a67
@ -10,6 +10,61 @@ import (
|
|||||||
"hakurei.app/container/vfs"
|
"hakurei.app/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Holding CAP_SYS_ADMIN within the user namespace that owns a process's mount namespace
|
||||||
|
allows that process to create bind mounts and mount the following types of filesystems:
|
||||||
|
- /proc (since Linux 3.8)
|
||||||
|
- /sys (since Linux 3.8)
|
||||||
|
- devpts (since Linux 3.9)
|
||||||
|
- tmpfs(5) (since Linux 3.9)
|
||||||
|
- ramfs (since Linux 3.9)
|
||||||
|
- mqueue (since Linux 3.9)
|
||||||
|
- bpf (since Linux 4.4)
|
||||||
|
- overlayfs (since Linux 5.11)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const (
|
||||||
|
// zeroString is a zero value string, it represents NULL when passed to mount.
|
||||||
|
zeroString = ""
|
||||||
|
|
||||||
|
// SourceNone is used when the source value is ignored,
|
||||||
|
// such as when remounting.
|
||||||
|
SourceNone = "none"
|
||||||
|
// SourceProc is used when mounting proc.
|
||||||
|
// Note that any source value is allowed when fstype is [FstypeProc].
|
||||||
|
SourceProc = "proc"
|
||||||
|
// SourceDevpts is used when mounting devpts.
|
||||||
|
// Note that any source value is allowed when fstype is [FstypeDevpts].
|
||||||
|
SourceDevpts = "devpts"
|
||||||
|
// SourceMqueue is used when mounting mqueue.
|
||||||
|
// Note that any source value is allowed when fstype is [FstypeMqueue].
|
||||||
|
SourceMqueue = "mqueue"
|
||||||
|
|
||||||
|
// SourceTmpfsDevtmpfs is used when mounting tmpfs representing a subset of host devtmpfs.
|
||||||
|
SourceTmpfsDevtmpfs = "devtmpfs"
|
||||||
|
// SourceTmpfsEphemeral is used when mounting a writable instance of tmpfs.
|
||||||
|
SourceTmpfsEphemeral = "ephemeral"
|
||||||
|
// SourceTmpfsReadonly is used when mounting a readonly instance of tmpfs.
|
||||||
|
SourceTmpfsReadonly = "readonly"
|
||||||
|
|
||||||
|
// FstypeNULL is used when the fstype value is ignored,
|
||||||
|
// such as when bind mounting or remounting.
|
||||||
|
FstypeNULL = zeroString
|
||||||
|
// FstypeProc represents the proc pseudo-filesystem.
|
||||||
|
// A fully visible instance of proc must be available in the mount namespace for proc to be mounted.
|
||||||
|
// This filesystem type is usually mounted on /proc.
|
||||||
|
FstypeProc = "proc"
|
||||||
|
// FstypeDevpts represents the devpts pseudo-filesystem.
|
||||||
|
// This type of filesystem is usually mounted on /dev/pts.
|
||||||
|
FstypeDevpts = "devpts"
|
||||||
|
// FstypeTmpfs represents the tmpfs filesystem.
|
||||||
|
// This filesystem type can be mounted anywhere in the container filesystem.
|
||||||
|
FstypeTmpfs = "tmpfs"
|
||||||
|
// FstypeMqueue represents the mqueue pseudo-filesystem.
|
||||||
|
// This filesystem type is usually mounted on /dev/mqueue.
|
||||||
|
FstypeMqueue = "mqueue"
|
||||||
|
)
|
||||||
|
|
||||||
// bindMount mounts source on target and recursively applies flags if MS_REC is set.
|
// bindMount mounts source on target and recursively applies flags if MS_REC is set.
|
||||||
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
||||||
if eq {
|
if eq {
|
||||||
@ -18,7 +73,7 @@ func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) err
|
|||||||
msg.Verbosef("resolved %q on %q flags %#x", source, target, flags)
|
msg.Verbosef("resolved %q on %q flags %#x", source, target, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Mount(source, target, "", MS_SILENT|MS_BIND|flags&MS_REC, ""); err != nil {
|
if err := Mount(source, target, FstypeNULL, MS_SILENT|MS_BIND|flags&MS_REC, zeroString); err != nil {
|
||||||
return wrapErrSuffix(err,
|
return wrapErrSuffix(err,
|
||||||
fmt.Sprintf("cannot mount %q on %q:", source, target))
|
fmt.Sprintf("cannot mount %q on %q:", source, target))
|
||||||
}
|
}
|
||||||
@ -98,7 +153,7 @@ func remountWithFlags(n *vfs.MountInfoNode, mf uintptr) error {
|
|||||||
|
|
||||||
if kf&mf != mf {
|
if kf&mf != mf {
|
||||||
return wrapErrSuffix(
|
return wrapErrSuffix(
|
||||||
Mount("none", n.Clean, "", MS_SILENT|MS_BIND|MS_REMOUNT|kf|mf, ""),
|
Mount(SourceNone, n.Clean, FstypeNULL, MS_SILENT|MS_BIND|MS_REMOUNT|kf|mf, zeroString),
|
||||||
fmt.Sprintf("cannot remount %q:", n.Clean))
|
fmt.Sprintf("cannot remount %q:", n.Clean))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -114,7 +169,7 @@ func mountTmpfs(fsname, name string, flags uintptr, size int, perm os.FileMode)
|
|||||||
opt += fmt.Sprintf(",size=%d", size)
|
opt += fmt.Sprintf(",size=%d", size)
|
||||||
}
|
}
|
||||||
return wrapErrSuffix(
|
return wrapErrSuffix(
|
||||||
Mount(fsname, target, "tmpfs", flags, opt),
|
Mount(fsname, target, FstypeTmpfs, flags, opt),
|
||||||
fmt.Sprintf("cannot mount tmpfs on %q:", name))
|
fmt.Sprintf("cannot mount tmpfs on %q:", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ func (p MountProcOp) apply(params *Params) error {
|
|||||||
if err := os.MkdirAll(target, params.ParentPerm); err != nil {
|
if err := os.MkdirAll(target, params.ParentPerm); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
}
|
}
|
||||||
return wrapErrSuffix(Mount("proc", target, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, ""),
|
return wrapErrSuffix(Mount(SourceProc, target, FstypeProc, MS_NOSUID|MS_NOEXEC|MS_NODEV, zeroString),
|
||||||
fmt.Sprintf("cannot mount proc on %q:", v))
|
fmt.Sprintf("cannot mount proc on %q:", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ func (d MountDevOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
target := toSysroot(v)
|
target := toSysroot(v)
|
||||||
|
|
||||||
if err := mountTmpfs("devtmpfs", v, MS_NOSUID|MS_NODEV, 0, params.ParentPerm); err != nil {
|
if err := mountTmpfs(SourceTmpfsDevtmpfs, v, MS_NOSUID|MS_NODEV, 0, params.ParentPerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ func (d MountDevOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Mount("devpts", devPtsPath, "devpts", MS_NOSUID|MS_NOEXEC,
|
if err := Mount(SourceDevpts, devPtsPath, FstypeDevpts, MS_NOSUID|MS_NOEXEC,
|
||||||
"newinstance,ptmxmode=0666,mode=620"); err != nil {
|
"newinstance,ptmxmode=0666,mode=620"); err != nil {
|
||||||
return wrapErrSuffix(err,
|
return wrapErrSuffix(err,
|
||||||
fmt.Sprintf("cannot mount devpts on %q:", devPtsPath))
|
fmt.Sprintf("cannot mount devpts on %q:", devPtsPath))
|
||||||
@ -294,7 +294,7 @@ func (m MountMqueueOp) apply(params *Params) error {
|
|||||||
if err := os.MkdirAll(target, params.ParentPerm); err != nil {
|
if err := os.MkdirAll(target, params.ParentPerm); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
}
|
}
|
||||||
return wrapErrSuffix(Mount("mqueue", target, "mqueue", MS_NOSUID|MS_NOEXEC|MS_NODEV, ""),
|
return wrapErrSuffix(Mount(SourceMqueue, target, FstypeMqueue, MS_NOSUID|MS_NOEXEC|MS_NODEV, zeroString),
|
||||||
fmt.Sprintf("cannot mount mqueue on %q:", v))
|
fmt.Sprintf("cannot mount mqueue on %q:", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,13 +306,13 @@ func init() { gob.Register(new(MountTmpfsOp)) }
|
|||||||
|
|
||||||
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
||||||
func (f *Ops) Tmpfs(dest string, size int, perm os.FileMode) *Ops {
|
func (f *Ops) Tmpfs(dest string, size int, perm os.FileMode) *Ops {
|
||||||
*f = append(*f, &MountTmpfsOp{"ephemeral", dest, MS_NOSUID | MS_NODEV, size, perm})
|
*f = append(*f, &MountTmpfsOp{SourceTmpfsEphemeral, dest, MS_NOSUID | MS_NODEV, size, perm})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Readonly appends an [Op] that mounts read-only tmpfs on container path [MountTmpfsOp.Path].
|
// Readonly appends an [Op] that mounts read-only tmpfs on container path [MountTmpfsOp.Path].
|
||||||
func (f *Ops) Readonly(dest string, perm os.FileMode) *Ops {
|
func (f *Ops) Readonly(dest string, perm os.FileMode) *Ops {
|
||||||
*f = append(*f, &MountTmpfsOp{"readonly", dest, MS_RDONLY | MS_NOSUID | MS_NODEV, 0, perm})
|
*f = append(*f, &MountTmpfsOp{SourceTmpfsReadonly, dest, MS_RDONLY | MS_NOSUID | MS_NODEV, 0, perm})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user