aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/helper.go
blob: fe0b164b3a385808f5c4c92001a4825cc82f88d1 (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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Package helper runs external helpers with optional sandboxing.
package helper

import (
	"context"
	"fmt"
	"io"
	"os"
	"time"

	"git.gensokyo.uk/security/hakurei/helper/proc"
)

var WaitDelay = 2 * time.Second

const (
	// HakureiHelper is set to 1 when args fd is enabled and 0 otherwise.
	HakureiHelper = "HAKUREI_HELPER"
	// HakureiStatus is set to 1 when stat fd is enabled and 0 otherwise.
	HakureiStatus = "HAKUREI_STATUS"
)

type Helper interface {
	// Start starts the helper process.
	Start() error
	// Wait blocks until Helper exits.
	Wait() error

	fmt.Stringer
}

func newHelperFiles(
	ctx context.Context,
	wt io.WriterTo,
	stat bool,
	argF func(argsFd, statFd int) []string,
	extraFiles []*os.File,
) (hl *helperFiles, args []string) {
	hl = new(helperFiles)
	hl.ctx = ctx
	hl.useArgsFd = wt != nil
	hl.useStatFd = stat

	hl.extraFiles = new(proc.ExtraFilesPre)
	for _, f := range extraFiles {
		_, v := hl.extraFiles.Append()
		*v = f
	}

	argsFd := -1
	if hl.useArgsFd {
		f := proc.NewWriterTo(wt)
		argsFd = int(proc.InitFile(f, hl.extraFiles))
		hl.files = append(hl.files, f)
	}

	statFd := -1
	if hl.useStatFd {
		f := proc.NewStat(&hl.stat)
		statFd = int(proc.InitFile(f, hl.extraFiles))
		hl.files = append(hl.files, f)
	}

	args = argF(argsFd, statFd)
	return
}

// helperFiles provides a generic wrapper around helper ipc.
type helperFiles struct {
	// whether argsFd is present
	useArgsFd bool
	// whether statFd is present
	useStatFd bool

	// closes statFd
	stat io.Closer
	// deferred extraFiles fulfillment
	files []proc.File
	// passed through to [proc.Fulfill] and [proc.InitFile]
	extraFiles *proc.ExtraFilesPre

	ctx context.Context
}