aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/init.go
diff options
context:
space:
mode:
Diffstat (limited to 'container/init.go')
-rw-r--r--container/init.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/container/init.go b/container/init.go
index 3b850073..41de58cd 100644
--- a/container/init.go
+++ b/container/init.go
@@ -11,11 +11,13 @@ import (
"path/filepath"
"slices"
"strconv"
+ "strings"
"sync"
"sync/atomic"
. "syscall"
"time"
+ "hakurei.app/check"
"hakurei.app/container/seccomp"
"hakurei.app/ext"
"hakurei.app/fhs"
@@ -240,6 +242,16 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
k.fatalf(msg, "cannot enter intermediate host path: %v", err)
}
+ if len(param.Binfmt) > 0 {
+ for i, e := range param.Binfmt {
+ if pathname, err := k.evalSymlinks(e.Interpreter.String()); err != nil {
+ k.fatal(msg, err)
+ } else if param.Binfmt[i].Interpreter, err = check.NewAbs(pathname); err != nil {
+ k.fatal(msg, err)
+ }
+ }
+ }
+
/* early is called right before pivot_root into intermediate root;
this step is mostly for gathering information that would otherwise be
difficult to obtain via library functions after pivot_root, and
@@ -295,6 +307,48 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
}
}
+ if len(param.Binfmt) > 0 {
+ const interpreter = "/interpreter"
+
+ if param.BinfmtPath == nil {
+ param.BinfmtPath = fhs.AbsProcSys.Append("fs/binfmt_misc")
+ }
+ binfmt := sysrootPath + param.BinfmtPath.String()
+ if err := k.mkdirAll(binfmt, 0); err != nil {
+ k.fatal(msg, err)
+ }
+ if err := k.mount(
+ SourceBinfmtMisc,
+ binfmt,
+ FstypeBinfmtMisc,
+ MS_NOSUID|MS_NOEXEC|MS_NODEV,
+ zeroString,
+ ); err != nil {
+ k.fatal(msg, err)
+ }
+
+ var buf strings.Builder
+ buf.Grow(1920)
+
+ register := binfmt + "/register"
+ for i, e := range param.Binfmt {
+ if err := k.symlink(hostPath+e.Interpreter.String(), interpreter); err != nil {
+ k.fatal(msg, err)
+ } else if err = k.writeFile(register, []byte(":"+
+ strconv.Itoa(i)+":"+
+ "M:"+
+ strconv.Itoa(int(e.Offset))+":"+
+ escapeBinfmt(&buf, e.Magic)+":"+
+ escapeBinfmt(&buf, e.Mask)+":"+
+ interpreter+":"+
+ "F"), 0); err != nil {
+ k.fatal(msg, err)
+ } else if err = k.remove(interpreter); err != nil {
+ k.fatal(msg, err)
+ }
+ }
+ }
+
// setup requiring host root complete at this point
if err := k.mount(hostDir, hostDir, zeroString, MS_SILENT|MS_REC|MS_PRIVATE, zeroString); err != nil {
k.fatalf(msg, "cannot make host root rprivate: %v", optionalErrorUnwrap(err))