aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/binfmt.go
diff options
context:
space:
mode:
Diffstat (limited to 'container/binfmt.go')
-rw-r--r--container/binfmt.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/container/binfmt.go b/container/binfmt.go
new file mode 100644
index 00000000..837e35b4
--- /dev/null
+++ b/container/binfmt.go
@@ -0,0 +1,46 @@
+package container
+
+import (
+ "strings"
+ "unsafe"
+
+ "hakurei.app/check"
+)
+
+// escapeBinfmt escapes magic/mask sequences in a [BinfmtEntry].
+func escapeBinfmt(buf *strings.Builder, s string) string {
+ const lowerhex = "0123456789abcdef"
+
+ buf.Reset()
+ for _, c := range unsafe.Slice(unsafe.StringData(s), len(s)) {
+ switch c {
+ case 0, '\\', ':':
+ buf.WriteString(`\x`)
+ buf.WriteByte(lowerhex[c>>4])
+ buf.WriteByte(lowerhex[c&0xf])
+
+ default:
+ buf.WriteByte(c)
+ }
+ }
+ return buf.String()
+}
+
+// BinfmtEntry is an entry to be registered by the init process.
+type BinfmtEntry struct {
+ // The offset of the magic/mask in the file, counted in bytes.
+ Offset byte
+ // The byte sequence binfmt_misc is matching for.
+ Magic string
+ // An (optional, defaults to all 0xff) mask.
+ Mask string
+ // The program that should be invoked with the binary as first argument.
+ Interpreter *check.Absolute
+}
+
+// Valid returns whether e can be registered into the kernel.
+func (e *BinfmtEntry) Valid() bool {
+ return e != nil &&
+ int(e.Offset)+max(len(e.Magic), len(e.Mask)) < 128 &&
+ e.Interpreter != nil && len(e.Interpreter.String()) < 128
+}