aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/sysctl.go
diff options
context:
space:
mode:
Diffstat (limited to 'container/sysctl.go')
-rw-r--r--container/sysctl.go69
1 files changed, 42 insertions, 27 deletions
diff --git a/container/sysctl.go b/container/sysctl.go
index e4b7af23..2cf47258 100644
--- a/container/sysctl.go
+++ b/container/sysctl.go
@@ -2,14 +2,32 @@ package container
import (
"bytes"
+ "fmt"
"os"
"strconv"
"sync"
"hakurei.app/fhs"
- "hakurei.app/message"
)
+// mustSysctlInt reads a sysctl path via proc, interprets it as a decimal
+// representation of an integer, and terminates the program if the read was
+// unsuccessful or the response is invalid.
+func mustSysctlInt(path string) (v int) {
+ p, err := os.ReadFile(fhs.ProcSys + path)
+ if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+
+ if v, err = strconv.Atoi(string(bytes.TrimSpace(p))); err != nil {
+ fmt.Printf("invalid sysctl response %q\n", string(p))
+ os.Exit(1)
+ }
+ return
+}
+
+// cached sysctl responses for populateSysctl
var (
kernelOverflowuid int
kernelOverflowgid int
@@ -18,34 +36,31 @@ var (
sysctlOnce sync.Once
)
-const (
- kernelOverflowuidPath = fhs.ProcSys + "kernel/overflowuid"
- kernelOverflowgidPath = fhs.ProcSys + "kernel/overflowgid"
- kernelCapLastCapPath = fhs.ProcSys + "kernel/cap_last_cap"
-)
-
-func mustReadSysctl(msg message.Msg) {
+// populateSysctl populates cached sysctl responses guarded by sysctlOnce.
+func populateSysctl() {
sysctlOnce.Do(func() {
- if v, err := os.ReadFile(kernelOverflowuidPath); err != nil {
- msg.GetLogger().Fatalf("cannot read %q: %v", kernelOverflowuidPath, err)
- } else if kernelOverflowuid, err = strconv.Atoi(string(bytes.TrimSpace(v))); err != nil {
- msg.GetLogger().Fatalf("cannot interpret %q: %v", kernelOverflowuidPath, err)
- }
+ kernelOverflowuid = mustSysctlInt("kernel/overflowuid")
+ kernelOverflowgid = mustSysctlInt("kernel/overflowgid")
+ kernelCapLastCap = mustSysctlInt("kernel/cap_last_cap")
+ })
+}
- if v, err := os.ReadFile(kernelOverflowgidPath); err != nil {
- msg.GetLogger().Fatalf("cannot read %q: %v", kernelOverflowgidPath, err)
- } else if kernelOverflowgid, err = strconv.Atoi(string(bytes.TrimSpace(v))); err != nil {
- msg.GetLogger().Fatalf("cannot interpret %q: %v", kernelOverflowgidPath, err)
- }
+// OverflowUID returns the fixed uid returned by legacy 16-bit UID system calls.
+// This value is also returned for unmapped UIDs in a user namespace.
+func OverflowUID() int {
+ populateSysctl()
+ return kernelOverflowuid
+}
- if v, err := os.ReadFile(kernelCapLastCapPath); err != nil {
- msg.GetLogger().Fatalf("cannot read %q: %v", kernelCapLastCapPath, err)
- } else if kernelCapLastCap, err = strconv.Atoi(string(bytes.TrimSpace(v))); err != nil {
- msg.GetLogger().Fatalf("cannot interpret %q: %v", kernelCapLastCapPath, err)
- }
- })
+// OverflowGID is like [OverflowUID], but for GID instead.
+func OverflowGID() int {
+ populateSysctl()
+ return kernelOverflowgid
}
-func OverflowUid(msg message.Msg) int { mustReadSysctl(msg); return kernelOverflowuid }
-func OverflowGid(msg message.Msg) int { mustReadSysctl(msg); return kernelOverflowgid }
-func LastCap(msg message.Msg) uintptr { mustReadSysctl(msg); return uintptr(kernelCapLastCap) }
+// lastcap returns the highest valid capability of the running kernel. Exports
+// CAP_LAST_CAP from the kernel.
+func lastcap() uintptr {
+ populateSysctl()
+ return uintptr(kernelCapLastCap)
+}