aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/binfmt.go
blob: 837e35b42f448fc1a64663666ab3b94e93e4b4c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
}