forked from rosa/hakurei
ext: move syscall wrappers from container
These are generally useful, and none of them are container-specific. Syscalls subtle to use and requiring container-specific setup remains in container. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -3,6 +3,8 @@ package container
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"hakurei.app/ext"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -51,15 +53,15 @@ func capset(hdrp *capHeader, datap *[2]capData) error {
|
||||
|
||||
// capBoundingSetDrop drops a capability from the calling thread's capability bounding set.
|
||||
func capBoundingSetDrop(cap uintptr) error {
|
||||
return Prctl(syscall.PR_CAPBSET_DROP, cap, 0)
|
||||
return ext.Prctl(syscall.PR_CAPBSET_DROP, cap, 0)
|
||||
}
|
||||
|
||||
// capAmbientClearAll clears the ambient capability set of the calling thread.
|
||||
func capAmbientClearAll() error {
|
||||
return Prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0)
|
||||
return ext.Prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0)
|
||||
}
|
||||
|
||||
// capAmbientRaise adds to the ambient capability set of the calling thread.
|
||||
func capAmbientRaise(cap uintptr) error {
|
||||
return Prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap)
|
||||
return ext.Prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/std"
|
||||
"hakurei.app/ext"
|
||||
"hakurei.app/internal/netlink"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
@@ -143,8 +144,8 @@ func (k direct) new(f func(k syscallDispatcher)) { go f(k) }
|
||||
|
||||
func (direct) lockOSThread() { runtime.LockOSThread() }
|
||||
|
||||
func (direct) setPtracer(pid uintptr) error { return SetPtracer(pid) }
|
||||
func (direct) setDumpable(dumpable uintptr) error { return SetDumpable(dumpable) }
|
||||
func (direct) setPtracer(pid uintptr) error { return ext.SetPtracer(pid) }
|
||||
func (direct) setDumpable(dumpable uintptr) error { return ext.SetDumpable(dumpable) }
|
||||
func (direct) setNoNewPrivs() error { return SetNoNewPrivs() }
|
||||
|
||||
func (direct) lastcap(msg message.Msg) uintptr { return LastCap(msg) }
|
||||
@@ -152,7 +153,7 @@ func (direct) capset(hdrp *capHeader, datap *[2]capData) error { return capset(h
|
||||
func (direct) capBoundingSetDrop(cap uintptr) error { return capBoundingSetDrop(cap) }
|
||||
func (direct) capAmbientClearAll() error { return capAmbientClearAll() }
|
||||
func (direct) capAmbientRaise(cap uintptr) error { return capAmbientRaise(cap) }
|
||||
func (direct) isatty(fd int) bool { return Isatty(fd) }
|
||||
func (direct) isatty(fd int) bool { return ext.Isatty(fd) }
|
||||
func (direct) receive(key string, e any, fdp *uintptr) (func() error, error) {
|
||||
return Receive(key, e, fdp)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"hakurei.app/container/fhs"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/ext"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
@@ -178,7 +179,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
||||
}
|
||||
|
||||
// write uid/gid map here so parent does not need to set dumpable
|
||||
if err := k.setDumpable(SUID_DUMP_USER); err != nil {
|
||||
if err := k.setDumpable(ext.SUID_DUMP_USER); err != nil {
|
||||
k.fatalf(msg, "cannot set SUID_DUMP_USER: %v", err)
|
||||
}
|
||||
if err := k.writeFile(fhs.Proc+"self/uid_map",
|
||||
@@ -196,7 +197,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
||||
0); err != nil {
|
||||
k.fatalf(msg, "%v", err)
|
||||
}
|
||||
if err := k.setDumpable(SUID_DUMP_DISABLE); err != nil {
|
||||
if err := k.setDumpable(ext.SUID_DUMP_DISABLE); err != nil {
|
||||
k.fatalf(msg, "cannot set SUID_DUMP_DISABLE: %v", err)
|
||||
}
|
||||
|
||||
@@ -290,7 +291,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
||||
|
||||
{
|
||||
var fd int
|
||||
if err := IgnoringEINTR(func() (err error) {
|
||||
if err := ext.IgnoringEINTR(func() (err error) {
|
||||
fd, err = k.open(fhs.Root, O_DIRECTORY|O_RDONLY, 0)
|
||||
return
|
||||
}); err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/ext"
|
||||
"hakurei.app/message"
|
||||
"hakurei.app/vfs"
|
||||
)
|
||||
@@ -115,7 +116,7 @@ func (p *procPaths) remount(msg message.Msg, target string, flags uintptr) error
|
||||
var targetKFinal string
|
||||
{
|
||||
var destFd int
|
||||
if err := IgnoringEINTR(func() (err error) {
|
||||
if err := ext.IgnoringEINTR(func() (err error) {
|
||||
destFd, err = p.k.open(targetFinal, O_PATH|O_CLOEXEC, 0)
|
||||
return
|
||||
}); err != nil {
|
||||
|
||||
@@ -7,40 +7,9 @@ import (
|
||||
"hakurei.app/ext"
|
||||
)
|
||||
|
||||
// Prctl manipulates various aspects of the behavior of the calling thread or process.
|
||||
func Prctl(op, arg2, arg3 uintptr) error {
|
||||
r, _, errno := Syscall(SYS_PRCTL, op, arg2, arg3)
|
||||
if r < 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPtracer allows processes to ptrace(2) the calling process.
|
||||
func SetPtracer(pid uintptr) error { return Prctl(PR_SET_PTRACER, pid, 0) }
|
||||
|
||||
// linux/sched/coredump.h
|
||||
const (
|
||||
SUID_DUMP_DISABLE = iota
|
||||
SUID_DUMP_USER
|
||||
)
|
||||
|
||||
// SetDumpable sets the "dumpable" attribute of the calling process.
|
||||
func SetDumpable(dumpable uintptr) error { return Prctl(PR_SET_DUMPABLE, dumpable, 0) }
|
||||
|
||||
// SetNoNewPrivs sets the calling thread's no_new_privs attribute.
|
||||
func SetNoNewPrivs() error { return Prctl(PR_SET_NO_NEW_PRIVS, 1, 0) }
|
||||
|
||||
// Isatty tests whether a file descriptor refers to a terminal.
|
||||
func Isatty(fd int) bool {
|
||||
var buf [8]byte
|
||||
r, _, _ := Syscall(
|
||||
SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
TIOCGWINSZ,
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
)
|
||||
return r == 0
|
||||
func SetNoNewPrivs() error {
|
||||
return ext.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0)
|
||||
}
|
||||
|
||||
// schedParam is equivalent to struct sched_param from include/linux/sched.h.
|
||||
@@ -73,19 +42,3 @@ func schedSetscheduler(tid int, policy ext.SchedPolicy, param *schedParam) error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IgnoringEINTR makes a function call and repeats it if it returns an
|
||||
// EINTR error. This appears to be required even though we install all
|
||||
// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
|
||||
// Also #20400 and #36644 are issues in which a signal handler is
|
||||
// installed without setting SA_RESTART. None of these are the common case,
|
||||
// but there are enough of them that it seems that we can't avoid
|
||||
// an EINTR loop.
|
||||
func IgnoringEINTR(fn func() error) error {
|
||||
for {
|
||||
err := fn()
|
||||
if err != EINTR {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user