Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b73a789dfe | |||
| 38b5ff0cec | |||
| 3c204b9b40 | |||
| 00771efeb4 | |||
| 61972d61f6 | |||
| fe40af7b7e | |||
| 12751932d1 | |||
| 41b49137a8 | |||
| c761e1de4d | |||
| a91920310d | |||
| 16e674782a | |||
| 47244daefb | |||
| 46fa104419 | |||
| 45953b3d9c | |||
| 42759e7a9f | |||
| 8e2d2c8246 | |||
| 299685775a | |||
| b7406cc4c4 | |||
| 690a0ed0d6 | |||
| a9d72a5eb1 | |||
| 6d14bb814f | |||
| be0e387ab0 | |||
| abeb67964f | |||
| bf5d10743f | |||
| 4e7aab07d5 | |||
| 15a66a2b31 | |||
| f347d44c22 | |||
| b5630f6883 | |||
| 17ffdb2dcf | |||
| ac34635890 | |||
| 9dec9dbc4b | |||
| 2f74adc8bd | |||
| d7e0104ae4 | |||
| bb92e3ada9 | |||
| fad419c2a2 | |||
| b1a1e73238 | |||
| 38e9128a8c | |||
| 7ee702a44e | |||
| 3d188ef884 |
2
.clang-format
Normal file
2
.clang-format
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ColumnLimit: 0
|
||||||
|
IndentWidth: 4
|
||||||
@ -11,21 +11,24 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal/dbus"
|
||||||
"hakurei.app/internal/env"
|
"hakurei.app/internal/env"
|
||||||
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/internal/outcome"
|
"hakurei.app/internal/outcome"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// optionalErrorUnwrap calls [errors.Unwrap] and returns the resulting value
|
||||||
|
// if it is not nil, or the original value if it is.
|
||||||
|
//
|
||||||
//go:linkname optionalErrorUnwrap hakurei.app/container.optionalErrorUnwrap
|
//go:linkname optionalErrorUnwrap hakurei.app/container.optionalErrorUnwrap
|
||||||
func optionalErrorUnwrap(_ error) error
|
func optionalErrorUnwrap(err error) error
|
||||||
|
|
||||||
func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command {
|
func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command {
|
||||||
var (
|
var (
|
||||||
@ -52,20 +55,26 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
|||||||
|
|
||||||
c.Command("shim", command.UsageInternal, func([]string) error { outcome.Shim(msg); return errSuccess })
|
c.Command("shim", command.UsageInternal, func([]string) error { outcome.Shim(msg); return errSuccess })
|
||||||
|
|
||||||
c.Command("app", "Load and start container from configuration file", func(args []string) error {
|
{
|
||||||
|
var (
|
||||||
|
flagIdentifierFile int
|
||||||
|
)
|
||||||
|
c.NewCommand("app", "Load and start container from configuration file", func(args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
log.Fatal("app requires at least 1 argument")
|
log.Fatal("app requires at least 1 argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
// config extraArgs...
|
|
||||||
config := tryPath(msg, args[0])
|
config := tryPath(msg, args[0])
|
||||||
if config != nil && config.Container != nil {
|
if config != nil && config.Container != nil {
|
||||||
config.Container.Args = append(config.Container.Args, args[1:]...)
|
config.Container.Args = append(config.Container.Args, args[1:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
outcome.Main(ctx, msg, config)
|
outcome.Main(ctx, msg, config, flagIdentifierFile)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
})
|
}).
|
||||||
|
Flag(&flagIdentifierFile, "identifier-fd", command.IntFlag(-1),
|
||||||
|
"Write identifier of current instance to fd after successful startup")
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var (
|
var (
|
||||||
@ -257,7 +266,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outcome.Main(ctx, msg, config)
|
outcome.Main(ctx, msg, config, -1)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}).
|
}).
|
||||||
Flag(&flagDBusConfigSession, "dbus-config", command.StringFlag("builtin"),
|
Flag(&flagDBusConfigSession, "dbus-config", command.StringFlag("builtin"),
|
||||||
@ -344,7 +353,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
|||||||
}).Flag(&flagShort, "short", command.BoolFlag(false), "Print instance id")
|
}).Flag(&flagShort, "short", command.BoolFlag(false), "Print instance id")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Command("version", "Display version information", func(args []string) error { fmt.Println(internal.Version()); return errSuccess })
|
c.Command("version", "Display version information", func(args []string) error { fmt.Println(info.Version()); return errSuccess })
|
||||||
c.Command("license", "Show full license text", func(args []string) error { fmt.Println(license); return errSuccess })
|
c.Command("license", "Show full license text", func(args []string) error { fmt.Println(license); return errSuccess })
|
||||||
c.Command("template", "Produce a config template", func(args []string) error { encodeJSON(log.Fatal, os.Stdout, false, hst.Template()); return errSuccess })
|
c.Command("template", "Produce a config template", func(args []string) error { encodeJSON(log.Fatal, os.Stdout, false, hst.Template()); return errSuccess })
|
||||||
c.Command("help", "Show this help message", func([]string) error { c.PrintHelp(); return errSuccess })
|
c.Command("help", "Show this help message", func([]string) error { c.PrintHelp(); return errSuccess })
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
package main_test
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname decodeJSON hakurei.app/cmd/hakurei.decodeJSON
|
|
||||||
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any)
|
|
||||||
|
|
||||||
func TestDecodeJSON(t *testing.T) {
|
func TestDecodeJSON(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@ -62,9 +57,6 @@ func TestDecodeJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname encodeJSON hakurei.app/cmd/hakurei.encodeJSON
|
|
||||||
func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any)
|
|
||||||
|
|
||||||
func TestEncodeJSON(t *testing.T) {
|
func TestEncodeJSON(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@ -74,7 +66,7 @@ func TestEncodeJSON(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{"marshaler", errorJSONMarshaler{},
|
{"marshaler", errorJSONMarshaler{},
|
||||||
`cannot encode json for main_test.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
|
`cannot encode json for main.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
|
||||||
{"default", func() {},
|
{"default", func() {},
|
||||||
`cannot write json: json: unsupported type: func()`},
|
`cannot write json: json: unsupported type: func()`},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/outcome"
|
||||||
"hakurei.app/internal/store"
|
"hakurei.app/internal/store"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
@ -53,14 +54,23 @@ func tryFd(msg message.Msg, name string) io.ReadCloser {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
|
if v < 3 { // reject standard streams
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
msg.Verbosef("trying config stream from %d", v)
|
msg.Verbosef("trying config stream from %d", v)
|
||||||
fd := uintptr(v)
|
fd := uintptr(v)
|
||||||
if _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_GETFD, 0); errno != 0 {
|
if _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_GETFD, 0); errno != 0 {
|
||||||
if errors.Is(errno, syscall.EBADF) {
|
if errors.Is(errno, syscall.EBADF) { // reject bad fd
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Fatalf("cannot get fd %d: %v", fd, errno)
|
log.Fatalf("cannot get fd %d: %v", fd, errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if outcome.IsPollDescriptor(fd) { // reject runtime internals
|
||||||
|
log.Fatalf("invalid config stream %d", fd)
|
||||||
|
}
|
||||||
|
|
||||||
return os.NewFile(fd, strconv.Itoa(v))
|
return os.NewFile(fd, strconv.Itoa(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
|
||||||
"hakurei.app/internal/env"
|
"hakurei.app/internal/env"
|
||||||
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/internal/outcome"
|
"hakurei.app/internal/outcome"
|
||||||
"hakurei.app/internal/store"
|
"hakurei.app/internal/store"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
@ -24,20 +24,20 @@ func printShowSystem(output io.Writer, short, flagJSON bool) {
|
|||||||
t := newPrinter(output)
|
t := newPrinter(output)
|
||||||
defer t.MustFlush()
|
defer t.MustFlush()
|
||||||
|
|
||||||
info := &hst.Info{Version: internal.Version(), User: new(outcome.Hsu).MustID(nil)}
|
hi := &hst.Info{Version: info.Version(), User: new(outcome.Hsu).MustID(nil)}
|
||||||
env.CopyPaths().Copy(&info.Paths, info.User)
|
env.CopyPaths().Copy(&hi.Paths, hi.User)
|
||||||
|
|
||||||
if flagJSON {
|
if flagJSON {
|
||||||
encodeJSON(log.Fatal, output, short, info)
|
encodeJSON(log.Fatal, output, short, hi)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Printf("Version:\t%s\n", info.Version)
|
t.Printf("Version:\t%s\n", hi.Version)
|
||||||
t.Printf("User:\t%d\n", info.User)
|
t.Printf("User:\t%d\n", hi.User)
|
||||||
t.Printf("TempDir:\t%s\n", info.TempDir)
|
t.Printf("TempDir:\t%s\n", hi.TempDir)
|
||||||
t.Printf("SharePath:\t%s\n", info.SharePath)
|
t.Printf("SharePath:\t%s\n", hi.SharePath)
|
||||||
t.Printf("RuntimePath:\t%s\n", info.RuntimePath)
|
t.Printf("RuntimePath:\t%s\n", hi.RuntimePath)
|
||||||
t.Printf("RunDirPath:\t%s\n", info.RunDirPath)
|
t.Printf("RunDirPath:\t%s\n", hi.RunDirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// printShowInstance writes a representation of [hst.State] or [hst.Config] to output.
|
// printShowInstance writes a representation of [hst.State] or [hst.Config] to output.
|
||||||
@ -90,12 +90,6 @@ func printShowInstance(
|
|||||||
t.Printf(" Groups:\t%s\n", strings.Join(config.Groups, ", "))
|
t.Printf(" Groups:\t%s\n", strings.Join(config.Groups, ", "))
|
||||||
}
|
}
|
||||||
if config.Container != nil {
|
if config.Container != nil {
|
||||||
if config.Container.Home != nil {
|
|
||||||
t.Printf(" Home:\t%s\n", config.Container.Home)
|
|
||||||
}
|
|
||||||
if config.Container.Hostname != "" {
|
|
||||||
t.Printf(" Hostname:\t%s\n", config.Container.Hostname)
|
|
||||||
}
|
|
||||||
flags := config.Container.Flags.String()
|
flags := config.Container.Flags.String()
|
||||||
|
|
||||||
// this is included in the upper hst.Config struct but is relevant here
|
// this is included in the upper hst.Config struct but is relevant here
|
||||||
@ -110,6 +104,12 @@ func printShowInstance(
|
|||||||
}
|
}
|
||||||
t.Printf(" Flags:\t%s\n", flags)
|
t.Printf(" Flags:\t%s\n", flags)
|
||||||
|
|
||||||
|
if config.Container.Home != nil {
|
||||||
|
t.Printf(" Home:\t%s\n", config.Container.Home)
|
||||||
|
}
|
||||||
|
if config.Container.Hostname != "" {
|
||||||
|
t.Printf(" Hostname:\t%s\n", config.Container.Hostname)
|
||||||
|
}
|
||||||
if config.Container.Path != nil {
|
if config.Container.Path != nil {
|
||||||
t.Printf(" Path:\t%s\n", config.Container.Path)
|
t.Printf(" Path:\t%s\n", config.Container.Path)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,9 +64,9 @@ func TestPrintShowInstance(t *testing.T) {
|
|||||||
Identity: 9 (org.chromium.Chromium)
|
Identity: 9 (org.chromium.Chromium)
|
||||||
Enablements: wayland, dbus, pulseaudio
|
Enablements: wayland, dbus, pulseaudio
|
||||||
Groups: video, dialout, plugdev
|
Groups: video, dialout, plugdev
|
||||||
|
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
||||||
Home: /data/data/org.chromium.Chromium
|
Home: /data/data/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
||||||
|
|
||||||
@ -161,9 +161,9 @@ App
|
|||||||
Identity: 9 (org.chromium.Chromium)
|
Identity: 9 (org.chromium.Chromium)
|
||||||
Enablements: wayland, dbus, pulseaudio
|
Enablements: wayland, dbus, pulseaudio
|
||||||
Groups: video, dialout, plugdev
|
Groups: video, dialout, plugdev
|
||||||
|
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
||||||
Home: /data/data/org.chromium.Chromium
|
Home: /data/data/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
|
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,11 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
var hakureiPathVal = internal.MustHakureiPath().String()
|
var hakureiPathVal = info.MustHakureiPath().String()
|
||||||
|
|
||||||
func mustRunApp(ctx context.Context, msg message.Msg, config *hst.Config, beforeFail func()) {
|
func mustRunApp(ctx context.Context, msg message.Msg, config *hst.Config, beforeFail func()) {
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -56,7 +56,7 @@ func NewAbs(pathname string) (*Absolute, error) {
|
|||||||
// MustAbs calls [NewAbs] and panics on error.
|
// MustAbs calls [NewAbs] and panics on error.
|
||||||
func MustAbs(pathname string) *Absolute {
|
func MustAbs(pathname string) *Absolute {
|
||||||
if a, err := NewAbs(pathname); err != nil {
|
if a, err := NewAbs(pathname); err != nil {
|
||||||
panic(err.Error())
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,13 +9,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
. "hakurei.app/container/check"
|
. "hakurei.app/container/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// unsafeAbs returns check.Absolute on any string value.
|
||||||
|
//
|
||||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||||
func unsafeAbs(_ string) *Absolute
|
func unsafeAbs(pathname string) *Absolute
|
||||||
|
|
||||||
func TestAbsoluteError(t *testing.T) {
|
func TestAbsoluteError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@ -82,9 +84,9 @@ func TestNewAbs(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
wantPanic := `path "etc" is not absolute`
|
wantPanic := &AbsoluteError{Pathname: "etc"}
|
||||||
|
|
||||||
if r := recover(); r != wantPanic {
|
if r := recover(); !reflect.DeepEqual(r, wantPanic) {
|
||||||
t.Errorf("MustAbs: panic = %v; want %v", r, wantPanic)
|
t.Errorf("MustAbs: panic = %v; want %v", r, wantPanic)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -143,11 +144,18 @@ func (e *StartError) Error() string {
|
|||||||
// Message returns a user-facing error message.
|
// Message returns a user-facing error message.
|
||||||
func (e *StartError) Message() string {
|
func (e *StartError) Message() string {
|
||||||
if e.Passthrough {
|
if e.Passthrough {
|
||||||
|
var (
|
||||||
|
numError *strconv.NumError
|
||||||
|
)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case errors.As(e.Err, new(*os.PathError)),
|
case errors.As(e.Err, new(*os.PathError)),
|
||||||
errors.As(e.Err, new(*os.SyscallError)):
|
errors.As(e.Err, new(*os.SyscallError)):
|
||||||
return "cannot " + e.Err.Error()
|
return "cannot " + e.Err.Error()
|
||||||
|
|
||||||
|
case errors.As(e.Err, &numError) && numError != nil:
|
||||||
|
return "cannot parse " + strconv.Quote(numError.Num) + ": " + numError.Err.Error()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return e.Err.Error()
|
return e.Err.Error()
|
||||||
}
|
}
|
||||||
@ -158,6 +166,39 @@ func (e *StartError) Message() string {
|
|||||||
return "cannot " + e.Error()
|
return "cannot " + e.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for ensureCloseOnExec
|
||||||
|
var (
|
||||||
|
closeOnExecOnce sync.Once
|
||||||
|
closeOnExecErr error
|
||||||
|
)
|
||||||
|
|
||||||
|
// ensureCloseOnExec ensures all currently open file descriptors have the syscall.FD_CLOEXEC flag set.
|
||||||
|
// This is only ran once as it is intended to handle files left open by the parent, and any file opened
|
||||||
|
// on this side should already have syscall.FD_CLOEXEC set.
|
||||||
|
func ensureCloseOnExec() error {
|
||||||
|
closeOnExecOnce.Do(func() {
|
||||||
|
const fdPrefixPath = "/proc/self/fd/"
|
||||||
|
|
||||||
|
var entries []os.DirEntry
|
||||||
|
if entries, closeOnExecErr = os.ReadDir(fdPrefixPath); closeOnExecErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fd int
|
||||||
|
for _, ent := range entries {
|
||||||
|
if fd, closeOnExecErr = strconv.Atoi(ent.Name()); closeOnExecErr != nil {
|
||||||
|
break // not reached
|
||||||
|
}
|
||||||
|
CloseOnExec(fd)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if closeOnExecErr == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &StartError{Fatal: true, Step: "set FD_CLOEXEC on all open files", Err: closeOnExecErr, Passthrough: true}
|
||||||
|
}
|
||||||
|
|
||||||
// Start starts the container init. The init process blocks until Serve is called.
|
// Start starts the container init. The init process blocks until Serve is called.
|
||||||
func (p *Container) Start() error {
|
func (p *Container) Start() error {
|
||||||
if p == nil || p.cmd == nil ||
|
if p == nil || p.cmd == nil ||
|
||||||
@ -168,6 +209,10 @@ func (p *Container) Start() error {
|
|||||||
return errors.New("container: already started")
|
return errors.New("container: already started")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := ensureCloseOnExec(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// map to overflow id to work around ownership checks
|
// map to overflow id to work around ownership checks
|
||||||
if p.Uid < 1 {
|
if p.Uid < 1 {
|
||||||
p.Uid = OverflowUid(p.msg)
|
p.Uid = OverflowUid(p.msg)
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import (
|
|||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/container/vfs"
|
"hakurei.app/container/vfs"
|
||||||
@ -29,6 +30,45 @@ import (
|
|||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Note: this package requires cgo, which is unavailable in the Go playground.
|
||||||
|
func Example() {
|
||||||
|
// Must be called early if the current process starts containers.
|
||||||
|
container.TryArgv0(nil)
|
||||||
|
|
||||||
|
// Configure the container.
|
||||||
|
z := container.New(context.Background(), nil)
|
||||||
|
z.Hostname = "hakurei-example"
|
||||||
|
z.Proc(fhs.AbsProc).Dev(fhs.AbsDev, true)
|
||||||
|
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
|
|
||||||
|
// Bind / for demonstration.
|
||||||
|
z.Bind(fhs.AbsRoot, fhs.AbsRoot, 0)
|
||||||
|
if name, err := exec.LookPath("hostname"); err != nil {
|
||||||
|
panic(err)
|
||||||
|
} else {
|
||||||
|
z.Path = check.MustAbs(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This completes the first stage of container setup and starts the container init process.
|
||||||
|
// The new process blocks until the Serve method is called.
|
||||||
|
if err := z.Start(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This serves the setup payload to the container init process,
|
||||||
|
// starting the second stage of container setup.
|
||||||
|
if err := z.Serve(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be called if the Start method succeeds.
|
||||||
|
if err := z.Wait(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: hakurei-example
|
||||||
|
}
|
||||||
|
|
||||||
func TestStartError(t *testing.T) {
|
func TestStartError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@ -44,8 +84,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Fatal: true,
|
Fatal: true,
|
||||||
Step: "set up params stream",
|
Step: "set up params stream",
|
||||||
Err: container.ErrReceiveEnv,
|
Err: container.ErrReceiveEnv,
|
||||||
},
|
}, "set up params stream: environment variable not set",
|
||||||
"set up params stream: environment variable not set",
|
|
||||||
container.ErrReceiveEnv, syscall.EBADF,
|
container.ErrReceiveEnv, syscall.EBADF,
|
||||||
"cannot set up params stream: environment variable not set"},
|
"cannot set up params stream: environment variable not set"},
|
||||||
|
|
||||||
@ -53,8 +92,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Fatal: true,
|
Fatal: true,
|
||||||
Step: "set up params stream",
|
Step: "set up params stream",
|
||||||
Err: &os.SyscallError{Syscall: "pipe2", Err: syscall.EBADF},
|
Err: &os.SyscallError{Syscall: "pipe2", Err: syscall.EBADF},
|
||||||
},
|
}, "set up params stream pipe2: bad file descriptor",
|
||||||
"set up params stream pipe2: bad file descriptor",
|
|
||||||
syscall.EBADF, os.ErrInvalid,
|
syscall.EBADF, os.ErrInvalid,
|
||||||
"cannot set up params stream pipe2: bad file descriptor"},
|
"cannot set up params stream pipe2: bad file descriptor"},
|
||||||
|
|
||||||
@ -62,16 +100,14 @@ func TestStartError(t *testing.T) {
|
|||||||
Fatal: true,
|
Fatal: true,
|
||||||
Step: "prctl(PR_SET_NO_NEW_PRIVS)",
|
Step: "prctl(PR_SET_NO_NEW_PRIVS)",
|
||||||
Err: syscall.EPERM,
|
Err: syscall.EPERM,
|
||||||
},
|
}, "prctl(PR_SET_NO_NEW_PRIVS): operation not permitted",
|
||||||
"prctl(PR_SET_NO_NEW_PRIVS): operation not permitted",
|
|
||||||
syscall.EPERM, syscall.EACCES,
|
syscall.EPERM, syscall.EACCES,
|
||||||
"cannot prctl(PR_SET_NO_NEW_PRIVS): operation not permitted"},
|
"cannot prctl(PR_SET_NO_NEW_PRIVS): operation not permitted"},
|
||||||
|
|
||||||
{"landlock abi", &container.StartError{
|
{"landlock abi", &container.StartError{
|
||||||
Step: "get landlock ABI",
|
Step: "get landlock ABI",
|
||||||
Err: syscall.ENOSYS,
|
Err: syscall.ENOSYS,
|
||||||
},
|
}, "get landlock ABI: function not implemented",
|
||||||
"get landlock ABI: function not implemented",
|
|
||||||
syscall.ENOSYS, syscall.ENOEXEC,
|
syscall.ENOSYS, syscall.ENOEXEC,
|
||||||
"cannot get landlock ABI: function not implemented"},
|
"cannot get landlock ABI: function not implemented"},
|
||||||
|
|
||||||
@ -79,8 +115,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Step: "kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET",
|
Step: "kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET",
|
||||||
Err: syscall.ENOSYS,
|
Err: syscall.ENOSYS,
|
||||||
Origin: true,
|
Origin: true,
|
||||||
},
|
}, "kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET",
|
||||||
"kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET",
|
|
||||||
syscall.ENOSYS, syscall.ENOSPC,
|
syscall.ENOSYS, syscall.ENOSPC,
|
||||||
"kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET"},
|
"kernel version too old for LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET"},
|
||||||
|
|
||||||
@ -88,8 +123,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Fatal: true,
|
Fatal: true,
|
||||||
Step: "create landlock ruleset",
|
Step: "create landlock ruleset",
|
||||||
Err: syscall.EBADFD,
|
Err: syscall.EBADFD,
|
||||||
},
|
}, "create landlock ruleset: file descriptor in bad state",
|
||||||
"create landlock ruleset: file descriptor in bad state",
|
|
||||||
syscall.EBADFD, syscall.EBADF,
|
syscall.EBADFD, syscall.EBADF,
|
||||||
"cannot create landlock ruleset: file descriptor in bad state"},
|
"cannot create landlock ruleset: file descriptor in bad state"},
|
||||||
|
|
||||||
@ -97,8 +131,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Fatal: true,
|
Fatal: true,
|
||||||
Step: "enforce landlock ruleset",
|
Step: "enforce landlock ruleset",
|
||||||
Err: syscall.ENOTRECOVERABLE,
|
Err: syscall.ENOTRECOVERABLE,
|
||||||
},
|
}, "enforce landlock ruleset: state not recoverable",
|
||||||
"enforce landlock ruleset: state not recoverable",
|
|
||||||
syscall.ENOTRECOVERABLE, syscall.ETIMEDOUT,
|
syscall.ENOTRECOVERABLE, syscall.ETIMEDOUT,
|
||||||
"cannot enforce landlock ruleset: state not recoverable"},
|
"cannot enforce landlock ruleset: state not recoverable"},
|
||||||
|
|
||||||
@ -109,8 +142,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Path: "/proc/nonexistent",
|
Path: "/proc/nonexistent",
|
||||||
Err: syscall.ENOENT,
|
Err: syscall.ENOENT,
|
||||||
}, Passthrough: true,
|
}, Passthrough: true,
|
||||||
},
|
}, "fork/exec /proc/nonexistent: no such file or directory",
|
||||||
"fork/exec /proc/nonexistent: no such file or directory",
|
|
||||||
syscall.ENOENT, syscall.ENOSYS,
|
syscall.ENOENT, syscall.ENOSYS,
|
||||||
"cannot fork/exec /proc/nonexistent: no such file or directory"},
|
"cannot fork/exec /proc/nonexistent: no such file or directory"},
|
||||||
|
|
||||||
@ -120,11 +152,19 @@ func TestStartError(t *testing.T) {
|
|||||||
Syscall: "open",
|
Syscall: "open",
|
||||||
Err: syscall.ENOSYS,
|
Err: syscall.ENOSYS,
|
||||||
}, Passthrough: true,
|
}, Passthrough: true,
|
||||||
},
|
}, "open: function not implemented",
|
||||||
"open: function not implemented",
|
|
||||||
syscall.ENOSYS, syscall.ENOENT,
|
syscall.ENOSYS, syscall.ENOENT,
|
||||||
"cannot open: function not implemented"},
|
"cannot open: function not implemented"},
|
||||||
|
|
||||||
|
{"start FD_CLOEXEC", &container.StartError{
|
||||||
|
Fatal: true,
|
||||||
|
Step: "set FD_CLOEXEC on all open files",
|
||||||
|
Err: func() error { _, err := strconv.Atoi("invalid"); return err }(),
|
||||||
|
Passthrough: true,
|
||||||
|
}, `strconv.Atoi: parsing "invalid": invalid syntax`,
|
||||||
|
strconv.ErrSyntax, os.ErrInvalid,
|
||||||
|
`cannot parse "invalid": invalid syntax`},
|
||||||
|
|
||||||
{"start other", &container.StartError{
|
{"start other", &container.StartError{
|
||||||
Step: "start container init",
|
Step: "start container init",
|
||||||
Err: &net.OpError{
|
Err: &net.OpError{
|
||||||
@ -132,8 +172,7 @@ func TestStartError(t *testing.T) {
|
|||||||
Net: "unix",
|
Net: "unix",
|
||||||
Err: syscall.ECONNREFUSED,
|
Err: syscall.ECONNREFUSED,
|
||||||
}, Passthrough: true,
|
}, Passthrough: true,
|
||||||
},
|
}, "dial unix: connection refused",
|
||||||
"dial unix: connection refused",
|
|
||||||
syscall.ECONNREFUSED, syscall.ECONNABORTED,
|
syscall.ECONNREFUSED, syscall.ECONNABORTED,
|
||||||
"dial unix: connection refused"},
|
"dial unix: connection refused"},
|
||||||
}
|
}
|
||||||
@ -722,12 +761,15 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*check.Absolute, args ...string) (c *container.Container) {
|
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*check.Absolute, args ...string) (c *container.Container) {
|
||||||
msg := message.New(nil)
|
msg := message.New(nil)
|
||||||
|
msg.SwapVerbose(testing.Verbose())
|
||||||
|
executable := check.MustAbs(container.MustExecutable(msg))
|
||||||
|
|
||||||
c = container.NewCommand(ctx, msg, absHelperInnerPath, "helper", args...)
|
c = container.NewCommand(ctx, msg, absHelperInnerPath, "helper", args...)
|
||||||
c.Env = append(c.Env, envDoCheck+"=1")
|
c.Env = append(c.Env, envDoCheck+"=1")
|
||||||
c.Bind(check.MustAbs(os.Args[0]), absHelperInnerPath, 0)
|
c.Bind(executable, absHelperInnerPath, 0)
|
||||||
|
|
||||||
// in case test has cgo enabled
|
// in case test has cgo enabled
|
||||||
if entries, err := ldd.Exec(ctx, msg, os.Args[0]); err != nil {
|
if entries, err := ldd.Resolve(ctx, msg, executable); err != nil {
|
||||||
log.Fatalf("ldd: %v", err)
|
log.Fatalf("ldd: %v", err)
|
||||||
} else {
|
} else {
|
||||||
*libPaths = ldd.Path(entries)
|
*libPaths = ldd.Path(entries)
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
package fhs
|
package fhs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
||||||
|
|
||||||
|
// unsafeAbs returns check.Absolute on any string value.
|
||||||
|
//
|
||||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||||
func unsafeAbs(_ string) *check.Absolute
|
func unsafeAbs(pathname string) *check.Absolute
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// AbsRoot is [Root] as [check.Absolute].
|
// AbsRoot is [Root] as [check.Absolute].
|
||||||
@ -34,6 +36,8 @@ var (
|
|||||||
|
|
||||||
// AbsDev is [Dev] as [check.Absolute].
|
// AbsDev is [Dev] as [check.Absolute].
|
||||||
AbsDev = unsafeAbs(Dev)
|
AbsDev = unsafeAbs(Dev)
|
||||||
|
// AbsDevShm is [DevShm] as [check.Absolute].
|
||||||
|
AbsDevShm = unsafeAbs(DevShm)
|
||||||
// AbsProc is [Proc] as [check.Absolute].
|
// AbsProc is [Proc] as [check.Absolute].
|
||||||
AbsProc = unsafeAbs(Proc)
|
AbsProc = unsafeAbs(Proc)
|
||||||
// AbsSys is [Sys] as [check.Absolute].
|
// AbsSys is [Sys] as [check.Absolute].
|
||||||
|
|||||||
@ -29,6 +29,8 @@ const (
|
|||||||
|
|
||||||
// Dev points to the root directory for device nodes.
|
// Dev points to the root directory for device nodes.
|
||||||
Dev = "/dev/"
|
Dev = "/dev/"
|
||||||
|
// DevShm is the place for POSIX shared memory segments, as created via shm_open(3).
|
||||||
|
DevShm = "/dev/shm/"
|
||||||
// Proc points to a virtual kernel file system exposing the process list and other functionality.
|
// Proc points to a virtual kernel file system exposing the process list and other functionality.
|
||||||
Proc = "/proc/"
|
Proc = "/proc/"
|
||||||
// ProcSys points to a hierarchy below /proc/ that exposes a number of kernel tunables.
|
// ProcSys points to a hierarchy below /proc/ that exposes a number of kernel tunables.
|
||||||
|
|||||||
@ -330,6 +330,10 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
k.umask(oldmask)
|
k.umask(oldmask)
|
||||||
|
|
||||||
|
if err := closeSetup(); err != nil {
|
||||||
|
k.fatalf(msg, "cannot close setup pipe: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
cmd := exec.Command(params.Path.String())
|
cmd := exec.Command(params.Path.String())
|
||||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
cmd.Args = params.Args
|
cmd.Args = params.Args
|
||||||
@ -342,11 +346,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := closeSetup(); err != nil {
|
|
||||||
k.printf(msg, "cannot close setup pipe: %v", err)
|
|
||||||
// not fatal
|
|
||||||
}
|
|
||||||
|
|
||||||
type winfo struct {
|
type winfo struct {
|
||||||
wpid int
|
wpid int
|
||||||
wstatus WaitStatus
|
wstatus WaitStatus
|
||||||
@ -427,6 +426,16 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if w.wpid == cmd.Process.Pid {
|
if w.wpid == cmd.Process.Pid {
|
||||||
|
// start timeout early
|
||||||
|
go func() { time.Sleep(params.AdoptWaitDelay); close(timeout) }()
|
||||||
|
|
||||||
|
// close initial process files; this also keeps them alive
|
||||||
|
for _, f := range extraFiles {
|
||||||
|
if err := f.Close(); err != nil {
|
||||||
|
msg.Verbose(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case w.wstatus.Exited():
|
case w.wstatus.Exited():
|
||||||
r = w.wstatus.ExitStatus()
|
r = w.wstatus.ExitStatus()
|
||||||
@ -440,8 +449,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
r = 255
|
r = 255
|
||||||
msg.Verbosef("initial process exited with status %#x", w.wstatus)
|
msg.Verbosef("initial process exited with status %#x", w.wstatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() { time.Sleep(params.AdoptWaitDelay); close(timeout) }()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
|
|||||||
@ -1983,6 +1983,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(13)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, stub.UniqueError(12)),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, stub.UniqueError(12)),
|
||||||
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(12)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(12)}}, nil, nil),
|
||||||
@ -2061,15 +2062,17 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
call("verbose", stub.ExpectArgs{[]any{"forwarding context cancellation"}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"forwarding context cancellation"}}, nil, nil),
|
||||||
// magicWait4Signal as ret causes wait4 stub to unblock
|
// magicWait4Signal as ret causes wait4 stub to unblock
|
||||||
call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, magicWait4Signal, stub.UniqueError(9)),
|
call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, magicWait4Signal, stub.UniqueError(9)),
|
||||||
call("printf", stub.ExpectArgs{"cannot forward cancellation: %v", []any{stub.UniqueError(9)}}, nil, nil),
|
call("printf", stub.ExpectArgs{"cannot forward cancellation: %v", []any{stub.UniqueError(9)}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
||||||
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil),
|
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
@ -2159,15 +2162,17 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- syscall.SIGQUIT }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- syscall.SIGQUIT }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"got %s, forwarding to initial process", []any{"quit"}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"got %s, forwarding to initial process", []any{"quit"}}, nil, nil),
|
||||||
// magicWait4Signal as ret causes wait4 stub to unblock
|
// magicWait4Signal as ret causes wait4 stub to unblock
|
||||||
call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", syscall.SIGQUIT}, magicWait4Signal, stub.UniqueError(0xfe)),
|
call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", syscall.SIGQUIT}, magicWait4Signal, stub.UniqueError(0xfe)),
|
||||||
call("printf", stub.ExpectArgs{"cannot forward signal: %v", []any{stub.UniqueError(0xfe)}}, nil, nil),
|
call("printf", stub.ExpectArgs{"cannot forward signal: %v", []any{stub.UniqueError(0xfe)}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
||||||
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", []any(nil)}, nil, nil),
|
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", []any(nil)}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
@ -2257,9 +2262,9 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"got %s", []any{"interrupt"}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"got %s", []any{"interrupt"}}, nil, nil),
|
||||||
@ -2348,11 +2353,13 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
||||||
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil),
|
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
@ -2441,11 +2448,13 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
call("exit", stub.ExpectArgs{0xce}, nil, nil),
|
call("exit", stub.ExpectArgs{0xce}, nil, nil),
|
||||||
@ -2577,11 +2586,13 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with code %d", []any{1}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with code %d", []any{1}}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
call("exit", stub.ExpectArgs{1}, nil, nil),
|
call("exit", stub.ExpectArgs{1}, nil, nil),
|
||||||
@ -2717,11 +2728,14 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("newFile", stub.ExpectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil),
|
||||||
call("newFile", stub.ExpectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil),
|
call("newFile", stub.ExpectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil),
|
||||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||||
|
call("fatalf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/bin/zsh")}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/bin/zsh")}}, nil, nil),
|
||||||
call("start", stub.ExpectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil),
|
call("start", stub.ExpectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil),
|
||||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil),
|
|
||||||
call("New", stub.ExpectArgs{}, nil, nil),
|
call("New", stub.ExpectArgs{}, nil, nil),
|
||||||
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
|
call("verbose", stub.ExpectArgs{[]any{os.ErrInvalid.Error()}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil),
|
||||||
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
call("beforeExit", stub.ExpectArgs{}, nil, nil),
|
||||||
call("exit", stub.ExpectArgs{0xff}, nil, nil),
|
call("exit", stub.ExpectArgs{0xff}, nil, nil),
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
#define LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
|
#define LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
int32_t hakurei_scmp_make_filter(int *ret_p, uintptr_t allocate_p,
|
int32_t hakurei_scmp_make_filter(
|
||||||
|
int *ret_p, uintptr_t allocate_p,
|
||||||
uint32_t arch, uint32_t multiarch,
|
uint32_t arch, uint32_t multiarch,
|
||||||
struct hakurei_syscall_rule *rules,
|
struct hakurei_syscall_rule *rules,
|
||||||
size_t rules_sz, hakurei_export_flag flags) {
|
size_t rules_sz, hakurei_export_flag flags) {
|
||||||
@ -72,11 +73,9 @@ int32_t hakurei_scmp_make_filter(int *ret_p, uintptr_t allocate_p,
|
|||||||
assert(rule->m_errno == EPERM || rule->m_errno == ENOSYS);
|
assert(rule->m_errno == EPERM || rule->m_errno == ENOSYS);
|
||||||
|
|
||||||
if (rule->arg)
|
if (rule->arg)
|
||||||
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno),
|
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 1, *rule->arg);
|
||||||
rule->syscall, 1, *rule->arg);
|
|
||||||
else
|
else
|
||||||
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno),
|
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 0);
|
||||||
rule->syscall, 0);
|
|
||||||
|
|
||||||
if (*ret_p == -EFAULT) {
|
if (*ret_p == -EFAULT) {
|
||||||
res = 4;
|
res = 4;
|
||||||
@ -93,22 +92,17 @@ int32_t hakurei_scmp_make_filter(int *ret_p, uintptr_t allocate_p,
|
|||||||
last_allowed_family = -1;
|
last_allowed_family = -1;
|
||||||
for (i = 0; i < LEN(socket_family_allowlist); i++) {
|
for (i = 0; i < LEN(socket_family_allowlist); i++) {
|
||||||
if (socket_family_allowlist[i].flags_mask != 0 &&
|
if (socket_family_allowlist[i].flags_mask != 0 &&
|
||||||
(socket_family_allowlist[i].flags_mask & flags) !=
|
(socket_family_allowlist[i].flags_mask & flags) != socket_family_allowlist[i].flags_mask)
|
||||||
socket_family_allowlist[i].flags_mask)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (disallowed = last_allowed_family + 1;
|
for (disallowed = last_allowed_family + 1; disallowed < socket_family_allowlist[i].family; disallowed++) {
|
||||||
disallowed < socket_family_allowlist[i].family; disallowed++) {
|
|
||||||
/* Blocklist the in-between valid families */
|
/* Blocklist the in-between valid families */
|
||||||
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT),
|
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, disallowed));
|
||||||
SCMP_SYS(socket), 1,
|
|
||||||
SCMP_A0(SCMP_CMP_EQ, disallowed));
|
|
||||||
}
|
}
|
||||||
last_allowed_family = socket_family_allowlist[i].family;
|
last_allowed_family = socket_family_allowlist[i].family;
|
||||||
}
|
}
|
||||||
/* Blocklist the rest */
|
/* Blocklist the rest */
|
||||||
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1,
|
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_GE, last_allowed_family + 1));
|
||||||
SCMP_A0(SCMP_CMP_GE, last_allowed_family + 1));
|
|
||||||
|
|
||||||
if (allocate_p == 0) {
|
if (allocate_p == 0) {
|
||||||
*ret_p = seccomp_load(ctx);
|
*ret_p = seccomp_load(ctx);
|
||||||
|
|||||||
@ -19,7 +19,8 @@ struct hakurei_syscall_rule {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void *hakurei_scmp_allocate(uintptr_t f, size_t len);
|
extern void *hakurei_scmp_allocate(uintptr_t f, size_t len);
|
||||||
int32_t hakurei_scmp_make_filter(int *ret_p, uintptr_t allocate_p,
|
int32_t hakurei_scmp_make_filter(
|
||||||
|
int *ret_p, uintptr_t allocate_p,
|
||||||
uint32_t arch, uint32_t multiarch,
|
uint32_t arch, uint32_t multiarch,
|
||||||
struct hakurei_syscall_rule *rules,
|
struct hakurei_syscall_rule *rules,
|
||||||
size_t rules_sz, hakurei_export_flag flags);
|
size_t rules_sz, hakurei_export_flag flags);
|
||||||
@ -215,10 +215,10 @@ const (
|
|||||||
|
|
||||||
// syscallResolveName resolves a syscall number by name via seccomp_syscall_resolve_name.
|
// syscallResolveName resolves a syscall number by name via seccomp_syscall_resolve_name.
|
||||||
// This function is only for testing the lookup tables and included here for convenience.
|
// This function is only for testing the lookup tables and included here for convenience.
|
||||||
func syscallResolveName(s string) (trap int, ok bool) {
|
func syscallResolveName(s string) (num std.ScmpSyscall, ok bool) {
|
||||||
v := C.CString(s)
|
v := C.CString(s)
|
||||||
trap = int(C.seccomp_syscall_resolve_name(v))
|
num = std.ScmpSyscall(C.seccomp_syscall_resolve_name(v))
|
||||||
C.free(unsafe.Pointer(v))
|
C.free(unsafe.Pointer(v))
|
||||||
ok = trap != C.__NR_SCMP_ERROR
|
ok = num != C.__NR_SCMP_ERROR
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,121 +68,121 @@ func Preset(presets FilterPreset, flags ExportFlag) (rules []NativeRule) {
|
|||||||
var (
|
var (
|
||||||
presetCommon = []NativeRule{
|
presetCommon = []NativeRule{
|
||||||
/* Block dmesg */
|
/* Block dmesg */
|
||||||
{ScmpSyscall(SYS_SYSLOG), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SYSLOG, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
/* Useless old syscall */
|
/* Useless old syscall */
|
||||||
{ScmpSyscall(SYS_USELIB), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_USELIB, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
/* Don't allow disabling accounting */
|
/* Don't allow disabling accounting */
|
||||||
{ScmpSyscall(SYS_ACCT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_ACCT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
/* Don't allow reading current quota use */
|
/* Don't allow reading current quota use */
|
||||||
{ScmpSyscall(SYS_QUOTACTL), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_QUOTACTL, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* Don't allow access to the kernel keyring */
|
/* Don't allow access to the kernel keyring */
|
||||||
{ScmpSyscall(SYS_ADD_KEY), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_ADD_KEY, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_KEYCTL), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_KEYCTL, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_REQUEST_KEY), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_REQUEST_KEY, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* Scary VM/NUMA ops */
|
/* Scary VM/NUMA ops */
|
||||||
{ScmpSyscall(SYS_MOVE_PAGES), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_MOVE_PAGES, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_MBIND), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_MBIND, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_GET_MEMPOLICY), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_GET_MEMPOLICY, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SET_MEMPOLICY), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SET_MEMPOLICY, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_MIGRATE_PAGES), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_MIGRATE_PAGES, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hakurei: project-specific extensions */
|
/* hakurei: project-specific extensions */
|
||||||
presetCommonExt = []NativeRule{
|
presetCommonExt = []NativeRule{
|
||||||
/* system calls for changing the system clock */
|
/* system calls for changing the system clock */
|
||||||
{ScmpSyscall(SYS_ADJTIMEX), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_ADJTIMEX, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CLOCK_ADJTIME), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CLOCK_ADJTIME, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CLOCK_ADJTIME64), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CLOCK_ADJTIME64, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CLOCK_SETTIME), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CLOCK_SETTIME, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CLOCK_SETTIME64), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CLOCK_SETTIME64, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETTIMEOFDAY), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETTIMEOFDAY, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* loading and unloading of kernel modules */
|
/* loading and unloading of kernel modules */
|
||||||
{ScmpSyscall(SYS_DELETE_MODULE), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_DELETE_MODULE, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FINIT_MODULE), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_FINIT_MODULE, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_INIT_MODULE), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_INIT_MODULE, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* system calls for rebooting and reboot preparation */
|
/* system calls for rebooting and reboot preparation */
|
||||||
{ScmpSyscall(SYS_KEXEC_FILE_LOAD), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_KEXEC_FILE_LOAD, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_KEXEC_LOAD), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_KEXEC_LOAD, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_REBOOT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_REBOOT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* system calls for enabling/disabling swap devices */
|
/* system calls for enabling/disabling swap devices */
|
||||||
{ScmpSyscall(SYS_SWAPOFF), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SWAPOFF, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SWAPON), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SWAPON, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
presetNamespace = []NativeRule{
|
presetNamespace = []NativeRule{
|
||||||
/* Don't allow subnamespace setups: */
|
/* Don't allow subnamespace setups: */
|
||||||
{ScmpSyscall(SYS_UNSHARE), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_UNSHARE, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETNS), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETNS, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_MOUNT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_MOUNT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_UMOUNT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_UMOUNT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_UMOUNT2), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_UMOUNT2, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_PIVOT_ROOT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_PIVOT_ROOT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CHROOT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CHROOT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CLONE), ScmpErrno(EPERM),
|
{Syscall: SNR_CLONE, Errno: ScmpErrno(EPERM),
|
||||||
&ScmpArgCmp{cloneArg, SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER}},
|
Arg: &ScmpArgCmp{Arg: cloneArg, Op: SCMP_CMP_MASKED_EQ, DatumA: CLONE_NEWUSER, DatumB: CLONE_NEWUSER}},
|
||||||
|
|
||||||
/* seccomp can't look into clone3()'s struct clone_args to check whether
|
/* seccomp can't look into clone3()'s struct clone_args to check whether
|
||||||
* the flags are OK, so we have no choice but to block clone3().
|
* the flags are OK, so we have no choice but to block clone3().
|
||||||
* Return ENOSYS so user-space will fall back to clone().
|
* Return ENOSYS so user-space will fall back to clone().
|
||||||
* (CVE-2021-41133; see also https://github.com/moby/moby/commit/9f6b562d)
|
* (CVE-2021-41133; see also https://github.com/moby/moby/commit/9f6b562d)
|
||||||
*/
|
*/
|
||||||
{ScmpSyscall(SYS_CLONE3), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_CLONE3, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
|
|
||||||
/* New mount manipulation APIs can also change our VFS. There's no
|
/* New mount manipulation APIs can also change our VFS. There's no
|
||||||
* legitimate reason to do these in the sandbox, so block all of them
|
* legitimate reason to do these in the sandbox, so block all of them
|
||||||
* rather than thinking about which ones might be dangerous.
|
* rather than thinking about which ones might be dangerous.
|
||||||
* (CVE-2021-41133) */
|
* (CVE-2021-41133) */
|
||||||
{ScmpSyscall(SYS_OPEN_TREE), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_OPEN_TREE, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_MOVE_MOUNT), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_MOVE_MOUNT, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FSOPEN), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_FSOPEN, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FSCONFIG), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_FSCONFIG, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FSMOUNT), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_FSMOUNT, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FSPICK), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_FSPICK, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_MOUNT_SETATTR), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_MOUNT_SETATTR, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hakurei: project-specific extensions */
|
/* hakurei: project-specific extensions */
|
||||||
presetNamespaceExt = []NativeRule{
|
presetNamespaceExt = []NativeRule{
|
||||||
/* changing file ownership */
|
/* changing file ownership */
|
||||||
{ScmpSyscall(SYS_CHOWN), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CHOWN, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_CHOWN32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_CHOWN32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FCHOWN), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_FCHOWN, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FCHOWN32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_FCHOWN32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_FCHOWNAT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_FCHOWNAT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_LCHOWN), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_LCHOWN, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_LCHOWN32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_LCHOWN32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
|
|
||||||
/* system calls for changing user ID and group ID credentials */
|
/* system calls for changing user ID and group ID credentials */
|
||||||
{ScmpSyscall(SYS_SETGID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETGID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETGID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETGID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETGROUPS), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETGROUPS, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETGROUPS32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETGROUPS32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETREGID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETREGID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETREGID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETREGID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETRESGID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETRESGID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETRESGID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETRESGID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETRESUID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETRESUID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETRESUID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETRESUID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETREUID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETREUID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETREUID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETREUID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETUID), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETUID, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SETUID32), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_SETUID32, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
presetTTY = []NativeRule{
|
presetTTY = []NativeRule{
|
||||||
/* Don't allow faking input to the controlling tty (CVE-2017-5226) */
|
/* Don't allow faking input to the controlling tty (CVE-2017-5226) */
|
||||||
{ScmpSyscall(SYS_IOCTL), ScmpErrno(EPERM),
|
{Syscall: SNR_IOCTL, Errno: ScmpErrno(EPERM),
|
||||||
&ScmpArgCmp{1, SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, TIOCSTI}},
|
Arg: &ScmpArgCmp{Arg: 1, Op: SCMP_CMP_MASKED_EQ, DatumA: 0xFFFFFFFF, DatumB: TIOCSTI}},
|
||||||
/* In the unlikely event that the controlling tty is a Linux virtual
|
/* In the unlikely event that the controlling tty is a Linux virtual
|
||||||
* console (/dev/tty2 or similar), copy/paste operations have an effect
|
* console (/dev/tty2 or similar), copy/paste operations have an effect
|
||||||
* similar to TIOCSTI (CVE-2023-28100) */
|
* similar to TIOCSTI (CVE-2023-28100) */
|
||||||
{ScmpSyscall(SYS_IOCTL), ScmpErrno(EPERM),
|
{Syscall: SNR_IOCTL, Errno: ScmpErrno(EPERM),
|
||||||
&ScmpArgCmp{1, SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, TIOCLINUX}},
|
Arg: &ScmpArgCmp{Arg: 1, Op: SCMP_CMP_MASKED_EQ, DatumA: 0xFFFFFFFF, DatumB: TIOCLINUX}},
|
||||||
}
|
}
|
||||||
|
|
||||||
presetEmu = []NativeRule{
|
presetEmu = []NativeRule{
|
||||||
@ -190,15 +190,15 @@ var (
|
|||||||
* so it's disabled as a hardening measure.
|
* so it's disabled as a hardening measure.
|
||||||
* However, it is required to run old 16-bit applications
|
* However, it is required to run old 16-bit applications
|
||||||
* as well as some Wine patches, so it's allowed in multiarch. */
|
* as well as some Wine patches, so it's allowed in multiarch. */
|
||||||
{ScmpSyscall(SYS_MODIFY_LDT), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_MODIFY_LDT, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hakurei: project-specific extensions */
|
/* hakurei: project-specific extensions */
|
||||||
presetEmuExt = []NativeRule{
|
presetEmuExt = []NativeRule{
|
||||||
{ScmpSyscall(SYS_SUBPAGE_PROT), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_SUBPAGE_PROT, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_SWITCH_ENDIAN), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_SWITCH_ENDIAN, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_VM86), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_VM86, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
{ScmpSyscall(SYS_VM86OLD), ScmpErrno(ENOSYS), nil},
|
{Syscall: SNR_VM86OLD, Errno: ScmpErrno(ENOSYS), Arg: nil},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -206,11 +206,11 @@ func presetDevel(allowedPersonality ScmpDatum) []NativeRule {
|
|||||||
return []NativeRule{
|
return []NativeRule{
|
||||||
/* Profiling operations; we expect these to be done by tools from outside
|
/* Profiling operations; we expect these to be done by tools from outside
|
||||||
* the sandbox. In particular perf has been the source of many CVEs. */
|
* the sandbox. In particular perf has been the source of many CVEs. */
|
||||||
{ScmpSyscall(SYS_PERF_EVENT_OPEN), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_PERF_EVENT_OPEN, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
/* Don't allow you to switch to bsd emulation or whatnot */
|
/* Don't allow you to switch to bsd emulation or whatnot */
|
||||||
{ScmpSyscall(SYS_PERSONALITY), ScmpErrno(EPERM),
|
{Syscall: SNR_PERSONALITY, Errno: ScmpErrno(EPERM),
|
||||||
&ScmpArgCmp{0, SCMP_CMP_NE, allowedPersonality, 0}},
|
Arg: &ScmpArgCmp{Arg: 0, Op: SCMP_CMP_NE, DatumA: allowedPersonality}},
|
||||||
|
|
||||||
{ScmpSyscall(SYS_PTRACE), ScmpErrno(EPERM), nil},
|
{Syscall: SNR_PTRACE, Errno: ScmpErrno(EPERM), Arg: nil},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ package std
|
|||||||
|
|
||||||
import . "syscall"
|
import . "syscall"
|
||||||
|
|
||||||
var syscallNum = map[string]int{
|
var syscallNum = map[string]ScmpSyscall{
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
my $offset = 0;
|
my $offset = 0;
|
||||||
@ -37,16 +37,14 @@ sub fmt {
|
|||||||
}
|
}
|
||||||
(my $name_upper = $name) =~ y/a-z/A-Z/;
|
(my $name_upper = $name) =~ y/a-z/A-Z/;
|
||||||
$num = $num + $offset;
|
$num = $num + $offset;
|
||||||
if($num > $syscall_cutoff_arch{$uname_arch}){ # not wired in Go standard library
|
if($num > $syscall_cutoff_arch{$uname_arch} && $state == 0){ # not wired in Go standard library
|
||||||
if($state < 0){
|
print " SYS_$name_upper = $num\n";
|
||||||
print " \"$name\": SYS_$name_upper,\n";
|
|
||||||
}
|
}
|
||||||
else{
|
elsif($state == -1){
|
||||||
print " SYS_$name_upper = $num;\n";
|
print " \"$name\": SNR_$name_upper,\n";
|
||||||
}
|
}
|
||||||
}
|
elsif($state == 1){
|
||||||
elsif($state < 0){
|
print " SNR_$name_upper ScmpSyscall = SYS_$name_upper\n";
|
||||||
print " \"$name\": SYS_$name_upper,\n";
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return;
|
return;
|
||||||
@ -81,10 +79,16 @@ while(<GCC>){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($state < 0){
|
if($state == -1){
|
||||||
$state = $state + 1;
|
|
||||||
print "}\n\nconst (\n";
|
print "}\n\nconst (\n";
|
||||||
goto GENERATE;
|
|
||||||
}
|
}
|
||||||
|
elsif($state == 0){
|
||||||
|
print ")\n\nconst (\n";
|
||||||
|
}
|
||||||
|
elsif($state == 1){
|
||||||
|
print ")";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
++$state;
|
||||||
|
goto GENERATE;
|
||||||
|
|
||||||
print ")";
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ type (
|
|||||||
// MarshalJSON resolves the name of [ScmpSyscall] and encodes it as a [json] string.
|
// MarshalJSON resolves the name of [ScmpSyscall] and encodes it as a [json] string.
|
||||||
// If such a name does not exist, the syscall number is encoded instead.
|
// If such a name does not exist, the syscall number is encoded instead.
|
||||||
func (num *ScmpSyscall) MarshalJSON() ([]byte, error) {
|
func (num *ScmpSyscall) MarshalJSON() ([]byte, error) {
|
||||||
n := int(*num)
|
n := *num
|
||||||
for name, cur := range Syscalls() {
|
for name, cur := range Syscalls() {
|
||||||
if cur == n {
|
if cur == n {
|
||||||
return json.Marshal(name)
|
return json.Marshal(name)
|
||||||
@ -70,7 +70,7 @@ func (num *ScmpSyscall) UnmarshalJSON(data []byte) error {
|
|||||||
if n, ok := SyscallResolveName(name); !ok {
|
if n, ok := SyscallResolveName(name); !ok {
|
||||||
return SyscallNameError(name)
|
return SyscallNameError(name)
|
||||||
} else {
|
} else {
|
||||||
*num = ScmpSyscall(n)
|
*num = n
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"syscall"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
@ -20,8 +19,8 @@ func TestScmpSyscall(t *testing.T) {
|
|||||||
want std.ScmpSyscall
|
want std.ScmpSyscall
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{"select", `"select"`, syscall.SYS_SELECT, nil},
|
{"epoll_create1", `"epoll_create1"`, std.SNR_EPOLL_CREATE1, nil},
|
||||||
{"clone3", `"clone3"`, std.SYS_CLONE3, nil},
|
{"clone3", `"clone3"`, std.SNR_CLONE3, nil},
|
||||||
|
|
||||||
{"oob", `-2147483647`, -math.MaxInt32,
|
{"oob", `-2147483647`, -math.MaxInt32,
|
||||||
&json.UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: 11}},
|
&json.UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: 11}},
|
||||||
|
|||||||
@ -3,8 +3,8 @@ package std
|
|||||||
import "iter"
|
import "iter"
|
||||||
|
|
||||||
// Syscalls returns an iterator over all wired syscalls.
|
// Syscalls returns an iterator over all wired syscalls.
|
||||||
func Syscalls() iter.Seq2[string, int] {
|
func Syscalls() iter.Seq2[string, ScmpSyscall] {
|
||||||
return func(yield func(string, int) bool) {
|
return func(yield func(string, ScmpSyscall) bool) {
|
||||||
for name, num := range syscallNum {
|
for name, num := range syscallNum {
|
||||||
if !yield(name, num) {
|
if !yield(name, num) {
|
||||||
return
|
return
|
||||||
@ -19,7 +19,7 @@ func Syscalls() iter.Seq2[string, int] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SyscallResolveName resolves a syscall number from its string representation.
|
// SyscallResolveName resolves a syscall number from its string representation.
|
||||||
func SyscallResolveName(name string) (num int, ok bool) {
|
func SyscallResolveName(name string) (num ScmpSyscall, ok bool) {
|
||||||
if num, ok = syscallNum[name]; ok {
|
if num, ok = syscallNum[name]; ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
package std
|
package std
|
||||||
|
|
||||||
var syscallNumExtra = map[string]int{
|
var syscallNumExtra = map[string]ScmpSyscall{
|
||||||
"kexec_file_load": SYS_KEXEC_FILE_LOAD,
|
"kexec_file_load": SNR_KEXEC_FILE_LOAD,
|
||||||
"subpage_prot": SYS_SUBPAGE_PROT,
|
"subpage_prot": SNR_SUBPAGE_PROT,
|
||||||
"switch_endian": SYS_SWITCH_ENDIAN,
|
"switch_endian": SNR_SWITCH_ENDIAN,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SYS_KEXEC_FILE_LOAD = __PNR_kexec_file_load
|
SNR_KEXEC_FILE_LOAD ScmpSyscall = __PNR_kexec_file_load
|
||||||
SYS_SUBPAGE_PROT = __PNR_subpage_prot
|
SNR_SUBPAGE_PROT ScmpSyscall = __PNR_subpage_prot
|
||||||
SYS_SWITCH_ENDIAN = __PNR_switch_endian
|
SNR_SWITCH_ENDIAN ScmpSyscall = __PNR_switch_endian
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,41 +1,41 @@
|
|||||||
package std
|
package std
|
||||||
|
|
||||||
var syscallNumExtra = map[string]int{
|
var syscallNumExtra = map[string]ScmpSyscall{
|
||||||
"umount": SYS_UMOUNT,
|
"umount": SNR_UMOUNT,
|
||||||
"subpage_prot": SYS_SUBPAGE_PROT,
|
"subpage_prot": SNR_SUBPAGE_PROT,
|
||||||
"switch_endian": SYS_SWITCH_ENDIAN,
|
"switch_endian": SNR_SWITCH_ENDIAN,
|
||||||
"vm86": SYS_VM86,
|
"vm86": SNR_VM86,
|
||||||
"vm86old": SYS_VM86OLD,
|
"vm86old": SNR_VM86OLD,
|
||||||
"clock_adjtime64": SYS_CLOCK_ADJTIME64,
|
"clock_adjtime64": SNR_CLOCK_ADJTIME64,
|
||||||
"clock_settime64": SYS_CLOCK_SETTIME64,
|
"clock_settime64": SNR_CLOCK_SETTIME64,
|
||||||
"chown32": SYS_CHOWN32,
|
"chown32": SNR_CHOWN32,
|
||||||
"fchown32": SYS_FCHOWN32,
|
"fchown32": SNR_FCHOWN32,
|
||||||
"lchown32": SYS_LCHOWN32,
|
"lchown32": SNR_LCHOWN32,
|
||||||
"setgid32": SYS_SETGID32,
|
"setgid32": SNR_SETGID32,
|
||||||
"setgroups32": SYS_SETGROUPS32,
|
"setgroups32": SNR_SETGROUPS32,
|
||||||
"setregid32": SYS_SETREGID32,
|
"setregid32": SNR_SETREGID32,
|
||||||
"setresgid32": SYS_SETRESGID32,
|
"setresgid32": SNR_SETRESGID32,
|
||||||
"setresuid32": SYS_SETRESUID32,
|
"setresuid32": SNR_SETRESUID32,
|
||||||
"setreuid32": SYS_SETREUID32,
|
"setreuid32": SNR_SETREUID32,
|
||||||
"setuid32": SYS_SETUID32,
|
"setuid32": SNR_SETUID32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SYS_UMOUNT = __PNR_umount
|
SNR_UMOUNT ScmpSyscall = __PNR_umount
|
||||||
SYS_SUBPAGE_PROT = __PNR_subpage_prot
|
SNR_SUBPAGE_PROT ScmpSyscall = __PNR_subpage_prot
|
||||||
SYS_SWITCH_ENDIAN = __PNR_switch_endian
|
SNR_SWITCH_ENDIAN ScmpSyscall = __PNR_switch_endian
|
||||||
SYS_VM86 = __PNR_vm86
|
SNR_VM86 ScmpSyscall = __PNR_vm86
|
||||||
SYS_VM86OLD = __PNR_vm86old
|
SNR_VM86OLD ScmpSyscall = __PNR_vm86old
|
||||||
SYS_CLOCK_ADJTIME64 = __PNR_clock_adjtime64
|
SNR_CLOCK_ADJTIME64 ScmpSyscall = __PNR_clock_adjtime64
|
||||||
SYS_CLOCK_SETTIME64 = __PNR_clock_settime64
|
SNR_CLOCK_SETTIME64 ScmpSyscall = __PNR_clock_settime64
|
||||||
SYS_CHOWN32 = __PNR_chown32
|
SNR_CHOWN32 ScmpSyscall = __PNR_chown32
|
||||||
SYS_FCHOWN32 = __PNR_fchown32
|
SNR_FCHOWN32 ScmpSyscall = __PNR_fchown32
|
||||||
SYS_LCHOWN32 = __PNR_lchown32
|
SNR_LCHOWN32 ScmpSyscall = __PNR_lchown32
|
||||||
SYS_SETGID32 = __PNR_setgid32
|
SNR_SETGID32 ScmpSyscall = __PNR_setgid32
|
||||||
SYS_SETGROUPS32 = __PNR_setgroups32
|
SNR_SETGROUPS32 ScmpSyscall = __PNR_setgroups32
|
||||||
SYS_SETREGID32 = __PNR_setregid32
|
SNR_SETREGID32 ScmpSyscall = __PNR_setregid32
|
||||||
SYS_SETRESGID32 = __PNR_setresgid32
|
SNR_SETRESGID32 ScmpSyscall = __PNR_setresgid32
|
||||||
SYS_SETRESUID32 = __PNR_setresuid32
|
SNR_SETRESUID32 ScmpSyscall = __PNR_setresuid32
|
||||||
SYS_SETREUID32 = __PNR_setreuid32
|
SNR_SETREUID32 ScmpSyscall = __PNR_setreuid32
|
||||||
SYS_SETUID32 = __PNR_setuid32
|
SNR_SETUID32 ScmpSyscall = __PNR_setuid32
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,50 +6,50 @@ const (
|
|||||||
SYS_NEWFSTATAT = syscall.SYS_FSTATAT
|
SYS_NEWFSTATAT = syscall.SYS_FSTATAT
|
||||||
)
|
)
|
||||||
|
|
||||||
var syscallNumExtra = map[string]int{
|
var syscallNumExtra = map[string]ScmpSyscall{
|
||||||
"uselib": SYS_USELIB,
|
"uselib": SNR_USELIB,
|
||||||
"clock_adjtime64": SYS_CLOCK_ADJTIME64,
|
"clock_adjtime64": SNR_CLOCK_ADJTIME64,
|
||||||
"clock_settime64": SYS_CLOCK_SETTIME64,
|
"clock_settime64": SNR_CLOCK_SETTIME64,
|
||||||
"umount": SYS_UMOUNT,
|
"umount": SNR_UMOUNT,
|
||||||
"chown": SYS_CHOWN,
|
"chown": SNR_CHOWN,
|
||||||
"chown32": SYS_CHOWN32,
|
"chown32": SNR_CHOWN32,
|
||||||
"fchown32": SYS_FCHOWN32,
|
"fchown32": SNR_FCHOWN32,
|
||||||
"lchown": SYS_LCHOWN,
|
"lchown": SNR_LCHOWN,
|
||||||
"lchown32": SYS_LCHOWN32,
|
"lchown32": SNR_LCHOWN32,
|
||||||
"setgid32": SYS_SETGID32,
|
"setgid32": SNR_SETGID32,
|
||||||
"setgroups32": SYS_SETGROUPS32,
|
"setgroups32": SNR_SETGROUPS32,
|
||||||
"setregid32": SYS_SETREGID32,
|
"setregid32": SNR_SETREGID32,
|
||||||
"setresgid32": SYS_SETRESGID32,
|
"setresgid32": SNR_SETRESGID32,
|
||||||
"setresuid32": SYS_SETRESUID32,
|
"setresuid32": SNR_SETRESUID32,
|
||||||
"setreuid32": SYS_SETREUID32,
|
"setreuid32": SNR_SETREUID32,
|
||||||
"setuid32": SYS_SETUID32,
|
"setuid32": SNR_SETUID32,
|
||||||
"modify_ldt": SYS_MODIFY_LDT,
|
"modify_ldt": SNR_MODIFY_LDT,
|
||||||
"subpage_prot": SYS_SUBPAGE_PROT,
|
"subpage_prot": SNR_SUBPAGE_PROT,
|
||||||
"switch_endian": SYS_SWITCH_ENDIAN,
|
"switch_endian": SNR_SWITCH_ENDIAN,
|
||||||
"vm86": SYS_VM86,
|
"vm86": SNR_VM86,
|
||||||
"vm86old": SYS_VM86OLD,
|
"vm86old": SNR_VM86OLD,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SYS_USELIB = __PNR_uselib
|
SNR_USELIB ScmpSyscall = __PNR_uselib
|
||||||
SYS_CLOCK_ADJTIME64 = __PNR_clock_adjtime64
|
SNR_CLOCK_ADJTIME64 ScmpSyscall = __PNR_clock_adjtime64
|
||||||
SYS_CLOCK_SETTIME64 = __PNR_clock_settime64
|
SNR_CLOCK_SETTIME64 ScmpSyscall = __PNR_clock_settime64
|
||||||
SYS_UMOUNT = __PNR_umount
|
SNR_UMOUNT ScmpSyscall = __PNR_umount
|
||||||
SYS_CHOWN = __PNR_chown
|
SNR_CHOWN ScmpSyscall = __PNR_chown
|
||||||
SYS_CHOWN32 = __PNR_chown32
|
SNR_CHOWN32 ScmpSyscall = __PNR_chown32
|
||||||
SYS_FCHOWN32 = __PNR_fchown32
|
SNR_FCHOWN32 ScmpSyscall = __PNR_fchown32
|
||||||
SYS_LCHOWN = __PNR_lchown
|
SNR_LCHOWN ScmpSyscall = __PNR_lchown
|
||||||
SYS_LCHOWN32 = __PNR_lchown32
|
SNR_LCHOWN32 ScmpSyscall = __PNR_lchown32
|
||||||
SYS_SETGID32 = __PNR_setgid32
|
SNR_SETGID32 ScmpSyscall = __PNR_setgid32
|
||||||
SYS_SETGROUPS32 = __PNR_setgroups32
|
SNR_SETGROUPS32 ScmpSyscall = __PNR_setgroups32
|
||||||
SYS_SETREGID32 = __PNR_setregid32
|
SNR_SETREGID32 ScmpSyscall = __PNR_setregid32
|
||||||
SYS_SETRESGID32 = __PNR_setresgid32
|
SNR_SETRESGID32 ScmpSyscall = __PNR_setresgid32
|
||||||
SYS_SETRESUID32 = __PNR_setresuid32
|
SNR_SETRESUID32 ScmpSyscall = __PNR_setresuid32
|
||||||
SYS_SETREUID32 = __PNR_setreuid32
|
SNR_SETREUID32 ScmpSyscall = __PNR_setreuid32
|
||||||
SYS_SETUID32 = __PNR_setuid32
|
SNR_SETUID32 ScmpSyscall = __PNR_setuid32
|
||||||
SYS_MODIFY_LDT = __PNR_modify_ldt
|
SNR_MODIFY_LDT ScmpSyscall = __PNR_modify_ldt
|
||||||
SYS_SUBPAGE_PROT = __PNR_subpage_prot
|
SNR_SUBPAGE_PROT ScmpSyscall = __PNR_subpage_prot
|
||||||
SYS_SWITCH_ENDIAN = __PNR_switch_endian
|
SNR_SWITCH_ENDIAN ScmpSyscall = __PNR_switch_endian
|
||||||
SYS_VM86 = __PNR_vm86
|
SNR_VM86 ScmpSyscall = __PNR_vm86
|
||||||
SYS_VM86OLD = __PNR_vm86old
|
SNR_VM86OLD ScmpSyscall = __PNR_vm86old
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,325 +5,325 @@ package std
|
|||||||
|
|
||||||
import . "syscall"
|
import . "syscall"
|
||||||
|
|
||||||
var syscallNum = map[string]int{
|
var syscallNum = map[string]ScmpSyscall{
|
||||||
"io_setup": SYS_IO_SETUP,
|
"io_setup": SNR_IO_SETUP,
|
||||||
"io_destroy": SYS_IO_DESTROY,
|
"io_destroy": SNR_IO_DESTROY,
|
||||||
"io_submit": SYS_IO_SUBMIT,
|
"io_submit": SNR_IO_SUBMIT,
|
||||||
"io_cancel": SYS_IO_CANCEL,
|
"io_cancel": SNR_IO_CANCEL,
|
||||||
"io_getevents": SYS_IO_GETEVENTS,
|
"io_getevents": SNR_IO_GETEVENTS,
|
||||||
"setxattr": SYS_SETXATTR,
|
"setxattr": SNR_SETXATTR,
|
||||||
"lsetxattr": SYS_LSETXATTR,
|
"lsetxattr": SNR_LSETXATTR,
|
||||||
"fsetxattr": SYS_FSETXATTR,
|
"fsetxattr": SNR_FSETXATTR,
|
||||||
"getxattr": SYS_GETXATTR,
|
"getxattr": SNR_GETXATTR,
|
||||||
"lgetxattr": SYS_LGETXATTR,
|
"lgetxattr": SNR_LGETXATTR,
|
||||||
"fgetxattr": SYS_FGETXATTR,
|
"fgetxattr": SNR_FGETXATTR,
|
||||||
"listxattr": SYS_LISTXATTR,
|
"listxattr": SNR_LISTXATTR,
|
||||||
"llistxattr": SYS_LLISTXATTR,
|
"llistxattr": SNR_LLISTXATTR,
|
||||||
"flistxattr": SYS_FLISTXATTR,
|
"flistxattr": SNR_FLISTXATTR,
|
||||||
"removexattr": SYS_REMOVEXATTR,
|
"removexattr": SNR_REMOVEXATTR,
|
||||||
"lremovexattr": SYS_LREMOVEXATTR,
|
"lremovexattr": SNR_LREMOVEXATTR,
|
||||||
"fremovexattr": SYS_FREMOVEXATTR,
|
"fremovexattr": SNR_FREMOVEXATTR,
|
||||||
"getcwd": SYS_GETCWD,
|
"getcwd": SNR_GETCWD,
|
||||||
"lookup_dcookie": SYS_LOOKUP_DCOOKIE,
|
"lookup_dcookie": SNR_LOOKUP_DCOOKIE,
|
||||||
"eventfd2": SYS_EVENTFD2,
|
"eventfd2": SNR_EVENTFD2,
|
||||||
"epoll_create1": SYS_EPOLL_CREATE1,
|
"epoll_create1": SNR_EPOLL_CREATE1,
|
||||||
"epoll_ctl": SYS_EPOLL_CTL,
|
"epoll_ctl": SNR_EPOLL_CTL,
|
||||||
"epoll_pwait": SYS_EPOLL_PWAIT,
|
"epoll_pwait": SNR_EPOLL_PWAIT,
|
||||||
"dup": SYS_DUP,
|
"dup": SNR_DUP,
|
||||||
"dup3": SYS_DUP3,
|
"dup3": SNR_DUP3,
|
||||||
"fcntl": SYS_FCNTL,
|
"fcntl": SNR_FCNTL,
|
||||||
"inotify_init1": SYS_INOTIFY_INIT1,
|
"inotify_init1": SNR_INOTIFY_INIT1,
|
||||||
"inotify_add_watch": SYS_INOTIFY_ADD_WATCH,
|
"inotify_add_watch": SNR_INOTIFY_ADD_WATCH,
|
||||||
"inotify_rm_watch": SYS_INOTIFY_RM_WATCH,
|
"inotify_rm_watch": SNR_INOTIFY_RM_WATCH,
|
||||||
"ioctl": SYS_IOCTL,
|
"ioctl": SNR_IOCTL,
|
||||||
"ioprio_set": SYS_IOPRIO_SET,
|
"ioprio_set": SNR_IOPRIO_SET,
|
||||||
"ioprio_get": SYS_IOPRIO_GET,
|
"ioprio_get": SNR_IOPRIO_GET,
|
||||||
"flock": SYS_FLOCK,
|
"flock": SNR_FLOCK,
|
||||||
"mknodat": SYS_MKNODAT,
|
"mknodat": SNR_MKNODAT,
|
||||||
"mkdirat": SYS_MKDIRAT,
|
"mkdirat": SNR_MKDIRAT,
|
||||||
"unlinkat": SYS_UNLINKAT,
|
"unlinkat": SNR_UNLINKAT,
|
||||||
"symlinkat": SYS_SYMLINKAT,
|
"symlinkat": SNR_SYMLINKAT,
|
||||||
"linkat": SYS_LINKAT,
|
"linkat": SNR_LINKAT,
|
||||||
"renameat": SYS_RENAMEAT,
|
"renameat": SNR_RENAMEAT,
|
||||||
"umount2": SYS_UMOUNT2,
|
"umount2": SNR_UMOUNT2,
|
||||||
"mount": SYS_MOUNT,
|
"mount": SNR_MOUNT,
|
||||||
"pivot_root": SYS_PIVOT_ROOT,
|
"pivot_root": SNR_PIVOT_ROOT,
|
||||||
"nfsservctl": SYS_NFSSERVCTL,
|
"nfsservctl": SNR_NFSSERVCTL,
|
||||||
"statfs": SYS_STATFS,
|
"statfs": SNR_STATFS,
|
||||||
"fstatfs": SYS_FSTATFS,
|
"fstatfs": SNR_FSTATFS,
|
||||||
"truncate": SYS_TRUNCATE,
|
"truncate": SNR_TRUNCATE,
|
||||||
"ftruncate": SYS_FTRUNCATE,
|
"ftruncate": SNR_FTRUNCATE,
|
||||||
"fallocate": SYS_FALLOCATE,
|
"fallocate": SNR_FALLOCATE,
|
||||||
"faccessat": SYS_FACCESSAT,
|
"faccessat": SNR_FACCESSAT,
|
||||||
"chdir": SYS_CHDIR,
|
"chdir": SNR_CHDIR,
|
||||||
"fchdir": SYS_FCHDIR,
|
"fchdir": SNR_FCHDIR,
|
||||||
"chroot": SYS_CHROOT,
|
"chroot": SNR_CHROOT,
|
||||||
"fchmod": SYS_FCHMOD,
|
"fchmod": SNR_FCHMOD,
|
||||||
"fchmodat": SYS_FCHMODAT,
|
"fchmodat": SNR_FCHMODAT,
|
||||||
"fchownat": SYS_FCHOWNAT,
|
"fchownat": SNR_FCHOWNAT,
|
||||||
"fchown": SYS_FCHOWN,
|
"fchown": SNR_FCHOWN,
|
||||||
"openat": SYS_OPENAT,
|
"openat": SNR_OPENAT,
|
||||||
"close": SYS_CLOSE,
|
"close": SNR_CLOSE,
|
||||||
"vhangup": SYS_VHANGUP,
|
"vhangup": SNR_VHANGUP,
|
||||||
"pipe2": SYS_PIPE2,
|
"pipe2": SNR_PIPE2,
|
||||||
"quotactl": SYS_QUOTACTL,
|
"quotactl": SNR_QUOTACTL,
|
||||||
"getdents64": SYS_GETDENTS64,
|
"getdents64": SNR_GETDENTS64,
|
||||||
"lseek": SYS_LSEEK,
|
"lseek": SNR_LSEEK,
|
||||||
"read": SYS_READ,
|
"read": SNR_READ,
|
||||||
"write": SYS_WRITE,
|
"write": SNR_WRITE,
|
||||||
"readv": SYS_READV,
|
"readv": SNR_READV,
|
||||||
"writev": SYS_WRITEV,
|
"writev": SNR_WRITEV,
|
||||||
"pread64": SYS_PREAD64,
|
"pread64": SNR_PREAD64,
|
||||||
"pwrite64": SYS_PWRITE64,
|
"pwrite64": SNR_PWRITE64,
|
||||||
"preadv": SYS_PREADV,
|
"preadv": SNR_PREADV,
|
||||||
"pwritev": SYS_PWRITEV,
|
"pwritev": SNR_PWRITEV,
|
||||||
"sendfile": SYS_SENDFILE,
|
"sendfile": SNR_SENDFILE,
|
||||||
"pselect6": SYS_PSELECT6,
|
"pselect6": SNR_PSELECT6,
|
||||||
"ppoll": SYS_PPOLL,
|
"ppoll": SNR_PPOLL,
|
||||||
"signalfd4": SYS_SIGNALFD4,
|
"signalfd4": SNR_SIGNALFD4,
|
||||||
"vmsplice": SYS_VMSPLICE,
|
"vmsplice": SNR_VMSPLICE,
|
||||||
"splice": SYS_SPLICE,
|
"splice": SNR_SPLICE,
|
||||||
"tee": SYS_TEE,
|
"tee": SNR_TEE,
|
||||||
"readlinkat": SYS_READLINKAT,
|
"readlinkat": SNR_READLINKAT,
|
||||||
"newfstatat": SYS_NEWFSTATAT,
|
"newfstatat": SNR_NEWFSTATAT,
|
||||||
"fstat": SYS_FSTAT,
|
"fstat": SNR_FSTAT,
|
||||||
"sync": SYS_SYNC,
|
"sync": SNR_SYNC,
|
||||||
"fsync": SYS_FSYNC,
|
"fsync": SNR_FSYNC,
|
||||||
"fdatasync": SYS_FDATASYNC,
|
"fdatasync": SNR_FDATASYNC,
|
||||||
"sync_file_range": SYS_SYNC_FILE_RANGE,
|
"sync_file_range": SNR_SYNC_FILE_RANGE,
|
||||||
"timerfd_create": SYS_TIMERFD_CREATE,
|
"timerfd_create": SNR_TIMERFD_CREATE,
|
||||||
"timerfd_settime": SYS_TIMERFD_SETTIME,
|
"timerfd_settime": SNR_TIMERFD_SETTIME,
|
||||||
"timerfd_gettime": SYS_TIMERFD_GETTIME,
|
"timerfd_gettime": SNR_TIMERFD_GETTIME,
|
||||||
"utimensat": SYS_UTIMENSAT,
|
"utimensat": SNR_UTIMENSAT,
|
||||||
"acct": SYS_ACCT,
|
"acct": SNR_ACCT,
|
||||||
"capget": SYS_CAPGET,
|
"capget": SNR_CAPGET,
|
||||||
"capset": SYS_CAPSET,
|
"capset": SNR_CAPSET,
|
||||||
"personality": SYS_PERSONALITY,
|
"personality": SNR_PERSONALITY,
|
||||||
"exit": SYS_EXIT,
|
"exit": SNR_EXIT,
|
||||||
"exit_group": SYS_EXIT_GROUP,
|
"exit_group": SNR_EXIT_GROUP,
|
||||||
"waitid": SYS_WAITID,
|
"waitid": SNR_WAITID,
|
||||||
"set_tid_address": SYS_SET_TID_ADDRESS,
|
"set_tid_address": SNR_SET_TID_ADDRESS,
|
||||||
"unshare": SYS_UNSHARE,
|
"unshare": SNR_UNSHARE,
|
||||||
"futex": SYS_FUTEX,
|
"futex": SNR_FUTEX,
|
||||||
"set_robust_list": SYS_SET_ROBUST_LIST,
|
"set_robust_list": SNR_SET_ROBUST_LIST,
|
||||||
"get_robust_list": SYS_GET_ROBUST_LIST,
|
"get_robust_list": SNR_GET_ROBUST_LIST,
|
||||||
"nanosleep": SYS_NANOSLEEP,
|
"nanosleep": SNR_NANOSLEEP,
|
||||||
"getitimer": SYS_GETITIMER,
|
"getitimer": SNR_GETITIMER,
|
||||||
"setitimer": SYS_SETITIMER,
|
"setitimer": SNR_SETITIMER,
|
||||||
"kexec_load": SYS_KEXEC_LOAD,
|
"kexec_load": SNR_KEXEC_LOAD,
|
||||||
"init_module": SYS_INIT_MODULE,
|
"init_module": SNR_INIT_MODULE,
|
||||||
"delete_module": SYS_DELETE_MODULE,
|
"delete_module": SNR_DELETE_MODULE,
|
||||||
"timer_create": SYS_TIMER_CREATE,
|
"timer_create": SNR_TIMER_CREATE,
|
||||||
"timer_gettime": SYS_TIMER_GETTIME,
|
"timer_gettime": SNR_TIMER_GETTIME,
|
||||||
"timer_getoverrun": SYS_TIMER_GETOVERRUN,
|
"timer_getoverrun": SNR_TIMER_GETOVERRUN,
|
||||||
"timer_settime": SYS_TIMER_SETTIME,
|
"timer_settime": SNR_TIMER_SETTIME,
|
||||||
"timer_delete": SYS_TIMER_DELETE,
|
"timer_delete": SNR_TIMER_DELETE,
|
||||||
"clock_settime": SYS_CLOCK_SETTIME,
|
"clock_settime": SNR_CLOCK_SETTIME,
|
||||||
"clock_gettime": SYS_CLOCK_GETTIME,
|
"clock_gettime": SNR_CLOCK_GETTIME,
|
||||||
"clock_getres": SYS_CLOCK_GETRES,
|
"clock_getres": SNR_CLOCK_GETRES,
|
||||||
"clock_nanosleep": SYS_CLOCK_NANOSLEEP,
|
"clock_nanosleep": SNR_CLOCK_NANOSLEEP,
|
||||||
"syslog": SYS_SYSLOG,
|
"syslog": SNR_SYSLOG,
|
||||||
"ptrace": SYS_PTRACE,
|
"ptrace": SNR_PTRACE,
|
||||||
"sched_setparam": SYS_SCHED_SETPARAM,
|
"sched_setparam": SNR_SCHED_SETPARAM,
|
||||||
"sched_setscheduler": SYS_SCHED_SETSCHEDULER,
|
"sched_setscheduler": SNR_SCHED_SETSCHEDULER,
|
||||||
"sched_getscheduler": SYS_SCHED_GETSCHEDULER,
|
"sched_getscheduler": SNR_SCHED_GETSCHEDULER,
|
||||||
"sched_getparam": SYS_SCHED_GETPARAM,
|
"sched_getparam": SNR_SCHED_GETPARAM,
|
||||||
"sched_setaffinity": SYS_SCHED_SETAFFINITY,
|
"sched_setaffinity": SNR_SCHED_SETAFFINITY,
|
||||||
"sched_getaffinity": SYS_SCHED_GETAFFINITY,
|
"sched_getaffinity": SNR_SCHED_GETAFFINITY,
|
||||||
"sched_yield": SYS_SCHED_YIELD,
|
"sched_yield": SNR_SCHED_YIELD,
|
||||||
"sched_get_priority_max": SYS_SCHED_GET_PRIORITY_MAX,
|
"sched_get_priority_max": SNR_SCHED_GET_PRIORITY_MAX,
|
||||||
"sched_get_priority_min": SYS_SCHED_GET_PRIORITY_MIN,
|
"sched_get_priority_min": SNR_SCHED_GET_PRIORITY_MIN,
|
||||||
"sched_rr_get_interval": SYS_SCHED_RR_GET_INTERVAL,
|
"sched_rr_get_interval": SNR_SCHED_RR_GET_INTERVAL,
|
||||||
"restart_syscall": SYS_RESTART_SYSCALL,
|
"restart_syscall": SNR_RESTART_SYSCALL,
|
||||||
"kill": SYS_KILL,
|
"kill": SNR_KILL,
|
||||||
"tkill": SYS_TKILL,
|
"tkill": SNR_TKILL,
|
||||||
"tgkill": SYS_TGKILL,
|
"tgkill": SNR_TGKILL,
|
||||||
"sigaltstack": SYS_SIGALTSTACK,
|
"sigaltstack": SNR_SIGALTSTACK,
|
||||||
"rt_sigsuspend": SYS_RT_SIGSUSPEND,
|
"rt_sigsuspend": SNR_RT_SIGSUSPEND,
|
||||||
"rt_sigaction": SYS_RT_SIGACTION,
|
"rt_sigaction": SNR_RT_SIGACTION,
|
||||||
"rt_sigprocmask": SYS_RT_SIGPROCMASK,
|
"rt_sigprocmask": SNR_RT_SIGPROCMASK,
|
||||||
"rt_sigpending": SYS_RT_SIGPENDING,
|
"rt_sigpending": SNR_RT_SIGPENDING,
|
||||||
"rt_sigtimedwait": SYS_RT_SIGTIMEDWAIT,
|
"rt_sigtimedwait": SNR_RT_SIGTIMEDWAIT,
|
||||||
"rt_sigqueueinfo": SYS_RT_SIGQUEUEINFO,
|
"rt_sigqueueinfo": SNR_RT_SIGQUEUEINFO,
|
||||||
"rt_sigreturn": SYS_RT_SIGRETURN,
|
"rt_sigreturn": SNR_RT_SIGRETURN,
|
||||||
"setpriority": SYS_SETPRIORITY,
|
"setpriority": SNR_SETPRIORITY,
|
||||||
"getpriority": SYS_GETPRIORITY,
|
"getpriority": SNR_GETPRIORITY,
|
||||||
"reboot": SYS_REBOOT,
|
"reboot": SNR_REBOOT,
|
||||||
"setregid": SYS_SETREGID,
|
"setregid": SNR_SETREGID,
|
||||||
"setgid": SYS_SETGID,
|
"setgid": SNR_SETGID,
|
||||||
"setreuid": SYS_SETREUID,
|
"setreuid": SNR_SETREUID,
|
||||||
"setuid": SYS_SETUID,
|
"setuid": SNR_SETUID,
|
||||||
"setresuid": SYS_SETRESUID,
|
"setresuid": SNR_SETRESUID,
|
||||||
"getresuid": SYS_GETRESUID,
|
"getresuid": SNR_GETRESUID,
|
||||||
"setresgid": SYS_SETRESGID,
|
"setresgid": SNR_SETRESGID,
|
||||||
"getresgid": SYS_GETRESGID,
|
"getresgid": SNR_GETRESGID,
|
||||||
"setfsuid": SYS_SETFSUID,
|
"setfsuid": SNR_SETFSUID,
|
||||||
"setfsgid": SYS_SETFSGID,
|
"setfsgid": SNR_SETFSGID,
|
||||||
"times": SYS_TIMES,
|
"times": SNR_TIMES,
|
||||||
"setpgid": SYS_SETPGID,
|
"setpgid": SNR_SETPGID,
|
||||||
"getpgid": SYS_GETPGID,
|
"getpgid": SNR_GETPGID,
|
||||||
"getsid": SYS_GETSID,
|
"getsid": SNR_GETSID,
|
||||||
"setsid": SYS_SETSID,
|
"setsid": SNR_SETSID,
|
||||||
"getgroups": SYS_GETGROUPS,
|
"getgroups": SNR_GETGROUPS,
|
||||||
"setgroups": SYS_SETGROUPS,
|
"setgroups": SNR_SETGROUPS,
|
||||||
"uname": SYS_UNAME,
|
"uname": SNR_UNAME,
|
||||||
"sethostname": SYS_SETHOSTNAME,
|
"sethostname": SNR_SETHOSTNAME,
|
||||||
"setdomainname": SYS_SETDOMAINNAME,
|
"setdomainname": SNR_SETDOMAINNAME,
|
||||||
"getrlimit": SYS_GETRLIMIT,
|
"getrlimit": SNR_GETRLIMIT,
|
||||||
"setrlimit": SYS_SETRLIMIT,
|
"setrlimit": SNR_SETRLIMIT,
|
||||||
"getrusage": SYS_GETRUSAGE,
|
"getrusage": SNR_GETRUSAGE,
|
||||||
"umask": SYS_UMASK,
|
"umask": SNR_UMASK,
|
||||||
"prctl": SYS_PRCTL,
|
"prctl": SNR_PRCTL,
|
||||||
"getcpu": SYS_GETCPU,
|
"getcpu": SNR_GETCPU,
|
||||||
"gettimeofday": SYS_GETTIMEOFDAY,
|
"gettimeofday": SNR_GETTIMEOFDAY,
|
||||||
"settimeofday": SYS_SETTIMEOFDAY,
|
"settimeofday": SNR_SETTIMEOFDAY,
|
||||||
"adjtimex": SYS_ADJTIMEX,
|
"adjtimex": SNR_ADJTIMEX,
|
||||||
"getpid": SYS_GETPID,
|
"getpid": SNR_GETPID,
|
||||||
"getppid": SYS_GETPPID,
|
"getppid": SNR_GETPPID,
|
||||||
"getuid": SYS_GETUID,
|
"getuid": SNR_GETUID,
|
||||||
"geteuid": SYS_GETEUID,
|
"geteuid": SNR_GETEUID,
|
||||||
"getgid": SYS_GETGID,
|
"getgid": SNR_GETGID,
|
||||||
"getegid": SYS_GETEGID,
|
"getegid": SNR_GETEGID,
|
||||||
"gettid": SYS_GETTID,
|
"gettid": SNR_GETTID,
|
||||||
"sysinfo": SYS_SYSINFO,
|
"sysinfo": SNR_SYSINFO,
|
||||||
"mq_open": SYS_MQ_OPEN,
|
"mq_open": SNR_MQ_OPEN,
|
||||||
"mq_unlink": SYS_MQ_UNLINK,
|
"mq_unlink": SNR_MQ_UNLINK,
|
||||||
"mq_timedsend": SYS_MQ_TIMEDSEND,
|
"mq_timedsend": SNR_MQ_TIMEDSEND,
|
||||||
"mq_timedreceive": SYS_MQ_TIMEDRECEIVE,
|
"mq_timedreceive": SNR_MQ_TIMEDRECEIVE,
|
||||||
"mq_notify": SYS_MQ_NOTIFY,
|
"mq_notify": SNR_MQ_NOTIFY,
|
||||||
"mq_getsetattr": SYS_MQ_GETSETATTR,
|
"mq_getsetattr": SNR_MQ_GETSETATTR,
|
||||||
"msgget": SYS_MSGGET,
|
"msgget": SNR_MSGGET,
|
||||||
"msgctl": SYS_MSGCTL,
|
"msgctl": SNR_MSGCTL,
|
||||||
"msgrcv": SYS_MSGRCV,
|
"msgrcv": SNR_MSGRCV,
|
||||||
"msgsnd": SYS_MSGSND,
|
"msgsnd": SNR_MSGSND,
|
||||||
"semget": SYS_SEMGET,
|
"semget": SNR_SEMGET,
|
||||||
"semctl": SYS_SEMCTL,
|
"semctl": SNR_SEMCTL,
|
||||||
"semtimedop": SYS_SEMTIMEDOP,
|
"semtimedop": SNR_SEMTIMEDOP,
|
||||||
"semop": SYS_SEMOP,
|
"semop": SNR_SEMOP,
|
||||||
"shmget": SYS_SHMGET,
|
"shmget": SNR_SHMGET,
|
||||||
"shmctl": SYS_SHMCTL,
|
"shmctl": SNR_SHMCTL,
|
||||||
"shmat": SYS_SHMAT,
|
"shmat": SNR_SHMAT,
|
||||||
"shmdt": SYS_SHMDT,
|
"shmdt": SNR_SHMDT,
|
||||||
"socket": SYS_SOCKET,
|
"socket": SNR_SOCKET,
|
||||||
"socketpair": SYS_SOCKETPAIR,
|
"socketpair": SNR_SOCKETPAIR,
|
||||||
"bind": SYS_BIND,
|
"bind": SNR_BIND,
|
||||||
"listen": SYS_LISTEN,
|
"listen": SNR_LISTEN,
|
||||||
"accept": SYS_ACCEPT,
|
"accept": SNR_ACCEPT,
|
||||||
"connect": SYS_CONNECT,
|
"connect": SNR_CONNECT,
|
||||||
"getsockname": SYS_GETSOCKNAME,
|
"getsockname": SNR_GETSOCKNAME,
|
||||||
"getpeername": SYS_GETPEERNAME,
|
"getpeername": SNR_GETPEERNAME,
|
||||||
"sendto": SYS_SENDTO,
|
"sendto": SNR_SENDTO,
|
||||||
"recvfrom": SYS_RECVFROM,
|
"recvfrom": SNR_RECVFROM,
|
||||||
"setsockopt": SYS_SETSOCKOPT,
|
"setsockopt": SNR_SETSOCKOPT,
|
||||||
"getsockopt": SYS_GETSOCKOPT,
|
"getsockopt": SNR_GETSOCKOPT,
|
||||||
"shutdown": SYS_SHUTDOWN,
|
"shutdown": SNR_SHUTDOWN,
|
||||||
"sendmsg": SYS_SENDMSG,
|
"sendmsg": SNR_SENDMSG,
|
||||||
"recvmsg": SYS_RECVMSG,
|
"recvmsg": SNR_RECVMSG,
|
||||||
"readahead": SYS_READAHEAD,
|
"readahead": SNR_READAHEAD,
|
||||||
"brk": SYS_BRK,
|
"brk": SNR_BRK,
|
||||||
"munmap": SYS_MUNMAP,
|
"munmap": SNR_MUNMAP,
|
||||||
"mremap": SYS_MREMAP,
|
"mremap": SNR_MREMAP,
|
||||||
"add_key": SYS_ADD_KEY,
|
"add_key": SNR_ADD_KEY,
|
||||||
"request_key": SYS_REQUEST_KEY,
|
"request_key": SNR_REQUEST_KEY,
|
||||||
"keyctl": SYS_KEYCTL,
|
"keyctl": SNR_KEYCTL,
|
||||||
"clone": SYS_CLONE,
|
"clone": SNR_CLONE,
|
||||||
"execve": SYS_EXECVE,
|
"execve": SNR_EXECVE,
|
||||||
"mmap": SYS_MMAP,
|
"mmap": SNR_MMAP,
|
||||||
"fadvise64": SYS_FADVISE64,
|
"fadvise64": SNR_FADVISE64,
|
||||||
"swapon": SYS_SWAPON,
|
"swapon": SNR_SWAPON,
|
||||||
"swapoff": SYS_SWAPOFF,
|
"swapoff": SNR_SWAPOFF,
|
||||||
"mprotect": SYS_MPROTECT,
|
"mprotect": SNR_MPROTECT,
|
||||||
"msync": SYS_MSYNC,
|
"msync": SNR_MSYNC,
|
||||||
"mlock": SYS_MLOCK,
|
"mlock": SNR_MLOCK,
|
||||||
"munlock": SYS_MUNLOCK,
|
"munlock": SNR_MUNLOCK,
|
||||||
"mlockall": SYS_MLOCKALL,
|
"mlockall": SNR_MLOCKALL,
|
||||||
"munlockall": SYS_MUNLOCKALL,
|
"munlockall": SNR_MUNLOCKALL,
|
||||||
"mincore": SYS_MINCORE,
|
"mincore": SNR_MINCORE,
|
||||||
"madvise": SYS_MADVISE,
|
"madvise": SNR_MADVISE,
|
||||||
"remap_file_pages": SYS_REMAP_FILE_PAGES,
|
"remap_file_pages": SNR_REMAP_FILE_PAGES,
|
||||||
"mbind": SYS_MBIND,
|
"mbind": SNR_MBIND,
|
||||||
"get_mempolicy": SYS_GET_MEMPOLICY,
|
"get_mempolicy": SNR_GET_MEMPOLICY,
|
||||||
"set_mempolicy": SYS_SET_MEMPOLICY,
|
"set_mempolicy": SNR_SET_MEMPOLICY,
|
||||||
"migrate_pages": SYS_MIGRATE_PAGES,
|
"migrate_pages": SNR_MIGRATE_PAGES,
|
||||||
"move_pages": SYS_MOVE_PAGES,
|
"move_pages": SNR_MOVE_PAGES,
|
||||||
"rt_tgsigqueueinfo": SYS_RT_TGSIGQUEUEINFO,
|
"rt_tgsigqueueinfo": SNR_RT_TGSIGQUEUEINFO,
|
||||||
"perf_event_open": SYS_PERF_EVENT_OPEN,
|
"perf_event_open": SNR_PERF_EVENT_OPEN,
|
||||||
"accept4": SYS_ACCEPT4,
|
"accept4": SNR_ACCEPT4,
|
||||||
"recvmmsg": SYS_RECVMMSG,
|
"recvmmsg": SNR_RECVMMSG,
|
||||||
"wait4": SYS_WAIT4,
|
"wait4": SNR_WAIT4,
|
||||||
"prlimit64": SYS_PRLIMIT64,
|
"prlimit64": SNR_PRLIMIT64,
|
||||||
"fanotify_init": SYS_FANOTIFY_INIT,
|
"fanotify_init": SNR_FANOTIFY_INIT,
|
||||||
"fanotify_mark": SYS_FANOTIFY_MARK,
|
"fanotify_mark": SNR_FANOTIFY_MARK,
|
||||||
"name_to_handle_at": SYS_NAME_TO_HANDLE_AT,
|
"name_to_handle_at": SNR_NAME_TO_HANDLE_AT,
|
||||||
"open_by_handle_at": SYS_OPEN_BY_HANDLE_AT,
|
"open_by_handle_at": SNR_OPEN_BY_HANDLE_AT,
|
||||||
"clock_adjtime": SYS_CLOCK_ADJTIME,
|
"clock_adjtime": SNR_CLOCK_ADJTIME,
|
||||||
"syncfs": SYS_SYNCFS,
|
"syncfs": SNR_SYNCFS,
|
||||||
"setns": SYS_SETNS,
|
"setns": SNR_SETNS,
|
||||||
"sendmmsg": SYS_SENDMMSG,
|
"sendmmsg": SNR_SENDMMSG,
|
||||||
"process_vm_readv": SYS_PROCESS_VM_READV,
|
"process_vm_readv": SNR_PROCESS_VM_READV,
|
||||||
"process_vm_writev": SYS_PROCESS_VM_WRITEV,
|
"process_vm_writev": SNR_PROCESS_VM_WRITEV,
|
||||||
"kcmp": SYS_KCMP,
|
"kcmp": SNR_KCMP,
|
||||||
"finit_module": SYS_FINIT_MODULE,
|
"finit_module": SNR_FINIT_MODULE,
|
||||||
"sched_setattr": SYS_SCHED_SETATTR,
|
"sched_setattr": SNR_SCHED_SETATTR,
|
||||||
"sched_getattr": SYS_SCHED_GETATTR,
|
"sched_getattr": SNR_SCHED_GETATTR,
|
||||||
"renameat2": SYS_RENAMEAT2,
|
"renameat2": SNR_RENAMEAT2,
|
||||||
"seccomp": SYS_SECCOMP,
|
"seccomp": SNR_SECCOMP,
|
||||||
"getrandom": SYS_GETRANDOM,
|
"getrandom": SNR_GETRANDOM,
|
||||||
"memfd_create": SYS_MEMFD_CREATE,
|
"memfd_create": SNR_MEMFD_CREATE,
|
||||||
"bpf": SYS_BPF,
|
"bpf": SNR_BPF,
|
||||||
"execveat": SYS_EXECVEAT,
|
"execveat": SNR_EXECVEAT,
|
||||||
"userfaultfd": SYS_USERFAULTFD,
|
"userfaultfd": SNR_USERFAULTFD,
|
||||||
"membarrier": SYS_MEMBARRIER,
|
"membarrier": SNR_MEMBARRIER,
|
||||||
"mlock2": SYS_MLOCK2,
|
"mlock2": SNR_MLOCK2,
|
||||||
"copy_file_range": SYS_COPY_FILE_RANGE,
|
"copy_file_range": SNR_COPY_FILE_RANGE,
|
||||||
"preadv2": SYS_PREADV2,
|
"preadv2": SNR_PREADV2,
|
||||||
"pwritev2": SYS_PWRITEV2,
|
"pwritev2": SNR_PWRITEV2,
|
||||||
"pkey_mprotect": SYS_PKEY_MPROTECT,
|
"pkey_mprotect": SNR_PKEY_MPROTECT,
|
||||||
"pkey_alloc": SYS_PKEY_ALLOC,
|
"pkey_alloc": SNR_PKEY_ALLOC,
|
||||||
"pkey_free": SYS_PKEY_FREE,
|
"pkey_free": SNR_PKEY_FREE,
|
||||||
"statx": SYS_STATX,
|
"statx": SNR_STATX,
|
||||||
"io_pgetevents": SYS_IO_PGETEVENTS,
|
"io_pgetevents": SNR_IO_PGETEVENTS,
|
||||||
"rseq": SYS_RSEQ,
|
"rseq": SNR_RSEQ,
|
||||||
"kexec_file_load": SYS_KEXEC_FILE_LOAD,
|
"kexec_file_load": SNR_KEXEC_FILE_LOAD,
|
||||||
"pidfd_send_signal": SYS_PIDFD_SEND_SIGNAL,
|
"pidfd_send_signal": SNR_PIDFD_SEND_SIGNAL,
|
||||||
"io_uring_setup": SYS_IO_URING_SETUP,
|
"io_uring_setup": SNR_IO_URING_SETUP,
|
||||||
"io_uring_enter": SYS_IO_URING_ENTER,
|
"io_uring_enter": SNR_IO_URING_ENTER,
|
||||||
"io_uring_register": SYS_IO_URING_REGISTER,
|
"io_uring_register": SNR_IO_URING_REGISTER,
|
||||||
"open_tree": SYS_OPEN_TREE,
|
"open_tree": SNR_OPEN_TREE,
|
||||||
"move_mount": SYS_MOVE_MOUNT,
|
"move_mount": SNR_MOVE_MOUNT,
|
||||||
"fsopen": SYS_FSOPEN,
|
"fsopen": SNR_FSOPEN,
|
||||||
"fsconfig": SYS_FSCONFIG,
|
"fsconfig": SNR_FSCONFIG,
|
||||||
"fsmount": SYS_FSMOUNT,
|
"fsmount": SNR_FSMOUNT,
|
||||||
"fspick": SYS_FSPICK,
|
"fspick": SNR_FSPICK,
|
||||||
"pidfd_open": SYS_PIDFD_OPEN,
|
"pidfd_open": SNR_PIDFD_OPEN,
|
||||||
"clone3": SYS_CLONE3,
|
"clone3": SNR_CLONE3,
|
||||||
"close_range": SYS_CLOSE_RANGE,
|
"close_range": SNR_CLOSE_RANGE,
|
||||||
"openat2": SYS_OPENAT2,
|
"openat2": SNR_OPENAT2,
|
||||||
"pidfd_getfd": SYS_PIDFD_GETFD,
|
"pidfd_getfd": SNR_PIDFD_GETFD,
|
||||||
"faccessat2": SYS_FACCESSAT2,
|
"faccessat2": SNR_FACCESSAT2,
|
||||||
"process_madvise": SYS_PROCESS_MADVISE,
|
"process_madvise": SNR_PROCESS_MADVISE,
|
||||||
"epoll_pwait2": SYS_EPOLL_PWAIT2,
|
"epoll_pwait2": SNR_EPOLL_PWAIT2,
|
||||||
"mount_setattr": SYS_MOUNT_SETATTR,
|
"mount_setattr": SNR_MOUNT_SETATTR,
|
||||||
"quotactl_fd": SYS_QUOTACTL_FD,
|
"quotactl_fd": SNR_QUOTACTL_FD,
|
||||||
"landlock_create_ruleset": SYS_LANDLOCK_CREATE_RULESET,
|
"landlock_create_ruleset": SNR_LANDLOCK_CREATE_RULESET,
|
||||||
"landlock_add_rule": SYS_LANDLOCK_ADD_RULE,
|
"landlock_add_rule": SNR_LANDLOCK_ADD_RULE,
|
||||||
"landlock_restrict_self": SYS_LANDLOCK_RESTRICT_SELF,
|
"landlock_restrict_self": SNR_LANDLOCK_RESTRICT_SELF,
|
||||||
"memfd_secret": SYS_MEMFD_SECRET,
|
"memfd_secret": SNR_MEMFD_SECRET,
|
||||||
"process_mrelease": SYS_PROCESS_MRELEASE,
|
"process_mrelease": SNR_PROCESS_MRELEASE,
|
||||||
"futex_waitv": SYS_FUTEX_WAITV,
|
"futex_waitv": SNR_FUTEX_WAITV,
|
||||||
"set_mempolicy_home_node": SYS_SET_MEMPOLICY_HOME_NODE,
|
"set_mempolicy_home_node": SNR_SET_MEMPOLICY_HOME_NODE,
|
||||||
"cachestat": SYS_CACHESTAT,
|
"cachestat": SNR_CACHESTAT,
|
||||||
"fchmodat2": SYS_FCHMODAT2,
|
"fchmodat2": SNR_FCHMODAT2,
|
||||||
"map_shadow_stack": SYS_MAP_SHADOW_STACK,
|
"map_shadow_stack": SNR_MAP_SHADOW_STACK,
|
||||||
"futex_wake": SYS_FUTEX_WAKE,
|
"futex_wake": SNR_FUTEX_WAKE,
|
||||||
"futex_wait": SYS_FUTEX_WAIT,
|
"futex_wait": SNR_FUTEX_WAIT,
|
||||||
"futex_requeue": SYS_FUTEX_REQUEUE,
|
"futex_requeue": SNR_FUTEX_REQUEUE,
|
||||||
"statmount": SYS_STATMOUNT,
|
"statmount": SNR_STATMOUNT,
|
||||||
"listmount": SYS_LISTMOUNT,
|
"listmount": SNR_LISTMOUNT,
|
||||||
"lsm_get_self_attr": SYS_LSM_GET_SELF_ATTR,
|
"lsm_get_self_attr": SNR_LSM_GET_SELF_ATTR,
|
||||||
"lsm_set_self_attr": SYS_LSM_SET_SELF_ATTR,
|
"lsm_set_self_attr": SNR_LSM_SET_SELF_ATTR,
|
||||||
"lsm_list_modules": SYS_LSM_LIST_MODULES,
|
"lsm_list_modules": SNR_LSM_LIST_MODULES,
|
||||||
"mseal": SYS_MSEAL,
|
"mseal": SNR_MSEAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -380,3 +380,324 @@ const (
|
|||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SNR_IO_SETUP ScmpSyscall = SYS_IO_SETUP
|
||||||
|
SNR_IO_DESTROY ScmpSyscall = SYS_IO_DESTROY
|
||||||
|
SNR_IO_SUBMIT ScmpSyscall = SYS_IO_SUBMIT
|
||||||
|
SNR_IO_CANCEL ScmpSyscall = SYS_IO_CANCEL
|
||||||
|
SNR_IO_GETEVENTS ScmpSyscall = SYS_IO_GETEVENTS
|
||||||
|
SNR_SETXATTR ScmpSyscall = SYS_SETXATTR
|
||||||
|
SNR_LSETXATTR ScmpSyscall = SYS_LSETXATTR
|
||||||
|
SNR_FSETXATTR ScmpSyscall = SYS_FSETXATTR
|
||||||
|
SNR_GETXATTR ScmpSyscall = SYS_GETXATTR
|
||||||
|
SNR_LGETXATTR ScmpSyscall = SYS_LGETXATTR
|
||||||
|
SNR_FGETXATTR ScmpSyscall = SYS_FGETXATTR
|
||||||
|
SNR_LISTXATTR ScmpSyscall = SYS_LISTXATTR
|
||||||
|
SNR_LLISTXATTR ScmpSyscall = SYS_LLISTXATTR
|
||||||
|
SNR_FLISTXATTR ScmpSyscall = SYS_FLISTXATTR
|
||||||
|
SNR_REMOVEXATTR ScmpSyscall = SYS_REMOVEXATTR
|
||||||
|
SNR_LREMOVEXATTR ScmpSyscall = SYS_LREMOVEXATTR
|
||||||
|
SNR_FREMOVEXATTR ScmpSyscall = SYS_FREMOVEXATTR
|
||||||
|
SNR_GETCWD ScmpSyscall = SYS_GETCWD
|
||||||
|
SNR_LOOKUP_DCOOKIE ScmpSyscall = SYS_LOOKUP_DCOOKIE
|
||||||
|
SNR_EVENTFD2 ScmpSyscall = SYS_EVENTFD2
|
||||||
|
SNR_EPOLL_CREATE1 ScmpSyscall = SYS_EPOLL_CREATE1
|
||||||
|
SNR_EPOLL_CTL ScmpSyscall = SYS_EPOLL_CTL
|
||||||
|
SNR_EPOLL_PWAIT ScmpSyscall = SYS_EPOLL_PWAIT
|
||||||
|
SNR_DUP ScmpSyscall = SYS_DUP
|
||||||
|
SNR_DUP3 ScmpSyscall = SYS_DUP3
|
||||||
|
SNR_FCNTL ScmpSyscall = SYS_FCNTL
|
||||||
|
SNR_INOTIFY_INIT1 ScmpSyscall = SYS_INOTIFY_INIT1
|
||||||
|
SNR_INOTIFY_ADD_WATCH ScmpSyscall = SYS_INOTIFY_ADD_WATCH
|
||||||
|
SNR_INOTIFY_RM_WATCH ScmpSyscall = SYS_INOTIFY_RM_WATCH
|
||||||
|
SNR_IOCTL ScmpSyscall = SYS_IOCTL
|
||||||
|
SNR_IOPRIO_SET ScmpSyscall = SYS_IOPRIO_SET
|
||||||
|
SNR_IOPRIO_GET ScmpSyscall = SYS_IOPRIO_GET
|
||||||
|
SNR_FLOCK ScmpSyscall = SYS_FLOCK
|
||||||
|
SNR_MKNODAT ScmpSyscall = SYS_MKNODAT
|
||||||
|
SNR_MKDIRAT ScmpSyscall = SYS_MKDIRAT
|
||||||
|
SNR_UNLINKAT ScmpSyscall = SYS_UNLINKAT
|
||||||
|
SNR_SYMLINKAT ScmpSyscall = SYS_SYMLINKAT
|
||||||
|
SNR_LINKAT ScmpSyscall = SYS_LINKAT
|
||||||
|
SNR_RENAMEAT ScmpSyscall = SYS_RENAMEAT
|
||||||
|
SNR_UMOUNT2 ScmpSyscall = SYS_UMOUNT2
|
||||||
|
SNR_MOUNT ScmpSyscall = SYS_MOUNT
|
||||||
|
SNR_PIVOT_ROOT ScmpSyscall = SYS_PIVOT_ROOT
|
||||||
|
SNR_NFSSERVCTL ScmpSyscall = SYS_NFSSERVCTL
|
||||||
|
SNR_STATFS ScmpSyscall = SYS_STATFS
|
||||||
|
SNR_FSTATFS ScmpSyscall = SYS_FSTATFS
|
||||||
|
SNR_TRUNCATE ScmpSyscall = SYS_TRUNCATE
|
||||||
|
SNR_FTRUNCATE ScmpSyscall = SYS_FTRUNCATE
|
||||||
|
SNR_FALLOCATE ScmpSyscall = SYS_FALLOCATE
|
||||||
|
SNR_FACCESSAT ScmpSyscall = SYS_FACCESSAT
|
||||||
|
SNR_CHDIR ScmpSyscall = SYS_CHDIR
|
||||||
|
SNR_FCHDIR ScmpSyscall = SYS_FCHDIR
|
||||||
|
SNR_CHROOT ScmpSyscall = SYS_CHROOT
|
||||||
|
SNR_FCHMOD ScmpSyscall = SYS_FCHMOD
|
||||||
|
SNR_FCHMODAT ScmpSyscall = SYS_FCHMODAT
|
||||||
|
SNR_FCHOWNAT ScmpSyscall = SYS_FCHOWNAT
|
||||||
|
SNR_FCHOWN ScmpSyscall = SYS_FCHOWN
|
||||||
|
SNR_OPENAT ScmpSyscall = SYS_OPENAT
|
||||||
|
SNR_CLOSE ScmpSyscall = SYS_CLOSE
|
||||||
|
SNR_VHANGUP ScmpSyscall = SYS_VHANGUP
|
||||||
|
SNR_PIPE2 ScmpSyscall = SYS_PIPE2
|
||||||
|
SNR_QUOTACTL ScmpSyscall = SYS_QUOTACTL
|
||||||
|
SNR_GETDENTS64 ScmpSyscall = SYS_GETDENTS64
|
||||||
|
SNR_LSEEK ScmpSyscall = SYS_LSEEK
|
||||||
|
SNR_READ ScmpSyscall = SYS_READ
|
||||||
|
SNR_WRITE ScmpSyscall = SYS_WRITE
|
||||||
|
SNR_READV ScmpSyscall = SYS_READV
|
||||||
|
SNR_WRITEV ScmpSyscall = SYS_WRITEV
|
||||||
|
SNR_PREAD64 ScmpSyscall = SYS_PREAD64
|
||||||
|
SNR_PWRITE64 ScmpSyscall = SYS_PWRITE64
|
||||||
|
SNR_PREADV ScmpSyscall = SYS_PREADV
|
||||||
|
SNR_PWRITEV ScmpSyscall = SYS_PWRITEV
|
||||||
|
SNR_SENDFILE ScmpSyscall = SYS_SENDFILE
|
||||||
|
SNR_PSELECT6 ScmpSyscall = SYS_PSELECT6
|
||||||
|
SNR_PPOLL ScmpSyscall = SYS_PPOLL
|
||||||
|
SNR_SIGNALFD4 ScmpSyscall = SYS_SIGNALFD4
|
||||||
|
SNR_VMSPLICE ScmpSyscall = SYS_VMSPLICE
|
||||||
|
SNR_SPLICE ScmpSyscall = SYS_SPLICE
|
||||||
|
SNR_TEE ScmpSyscall = SYS_TEE
|
||||||
|
SNR_READLINKAT ScmpSyscall = SYS_READLINKAT
|
||||||
|
SNR_NEWFSTATAT ScmpSyscall = SYS_NEWFSTATAT
|
||||||
|
SNR_FSTAT ScmpSyscall = SYS_FSTAT
|
||||||
|
SNR_SYNC ScmpSyscall = SYS_SYNC
|
||||||
|
SNR_FSYNC ScmpSyscall = SYS_FSYNC
|
||||||
|
SNR_FDATASYNC ScmpSyscall = SYS_FDATASYNC
|
||||||
|
SNR_SYNC_FILE_RANGE ScmpSyscall = SYS_SYNC_FILE_RANGE
|
||||||
|
SNR_TIMERFD_CREATE ScmpSyscall = SYS_TIMERFD_CREATE
|
||||||
|
SNR_TIMERFD_SETTIME ScmpSyscall = SYS_TIMERFD_SETTIME
|
||||||
|
SNR_TIMERFD_GETTIME ScmpSyscall = SYS_TIMERFD_GETTIME
|
||||||
|
SNR_UTIMENSAT ScmpSyscall = SYS_UTIMENSAT
|
||||||
|
SNR_ACCT ScmpSyscall = SYS_ACCT
|
||||||
|
SNR_CAPGET ScmpSyscall = SYS_CAPGET
|
||||||
|
SNR_CAPSET ScmpSyscall = SYS_CAPSET
|
||||||
|
SNR_PERSONALITY ScmpSyscall = SYS_PERSONALITY
|
||||||
|
SNR_EXIT ScmpSyscall = SYS_EXIT
|
||||||
|
SNR_EXIT_GROUP ScmpSyscall = SYS_EXIT_GROUP
|
||||||
|
SNR_WAITID ScmpSyscall = SYS_WAITID
|
||||||
|
SNR_SET_TID_ADDRESS ScmpSyscall = SYS_SET_TID_ADDRESS
|
||||||
|
SNR_UNSHARE ScmpSyscall = SYS_UNSHARE
|
||||||
|
SNR_FUTEX ScmpSyscall = SYS_FUTEX
|
||||||
|
SNR_SET_ROBUST_LIST ScmpSyscall = SYS_SET_ROBUST_LIST
|
||||||
|
SNR_GET_ROBUST_LIST ScmpSyscall = SYS_GET_ROBUST_LIST
|
||||||
|
SNR_NANOSLEEP ScmpSyscall = SYS_NANOSLEEP
|
||||||
|
SNR_GETITIMER ScmpSyscall = SYS_GETITIMER
|
||||||
|
SNR_SETITIMER ScmpSyscall = SYS_SETITIMER
|
||||||
|
SNR_KEXEC_LOAD ScmpSyscall = SYS_KEXEC_LOAD
|
||||||
|
SNR_INIT_MODULE ScmpSyscall = SYS_INIT_MODULE
|
||||||
|
SNR_DELETE_MODULE ScmpSyscall = SYS_DELETE_MODULE
|
||||||
|
SNR_TIMER_CREATE ScmpSyscall = SYS_TIMER_CREATE
|
||||||
|
SNR_TIMER_GETTIME ScmpSyscall = SYS_TIMER_GETTIME
|
||||||
|
SNR_TIMER_GETOVERRUN ScmpSyscall = SYS_TIMER_GETOVERRUN
|
||||||
|
SNR_TIMER_SETTIME ScmpSyscall = SYS_TIMER_SETTIME
|
||||||
|
SNR_TIMER_DELETE ScmpSyscall = SYS_TIMER_DELETE
|
||||||
|
SNR_CLOCK_SETTIME ScmpSyscall = SYS_CLOCK_SETTIME
|
||||||
|
SNR_CLOCK_GETTIME ScmpSyscall = SYS_CLOCK_GETTIME
|
||||||
|
SNR_CLOCK_GETRES ScmpSyscall = SYS_CLOCK_GETRES
|
||||||
|
SNR_CLOCK_NANOSLEEP ScmpSyscall = SYS_CLOCK_NANOSLEEP
|
||||||
|
SNR_SYSLOG ScmpSyscall = SYS_SYSLOG
|
||||||
|
SNR_PTRACE ScmpSyscall = SYS_PTRACE
|
||||||
|
SNR_SCHED_SETPARAM ScmpSyscall = SYS_SCHED_SETPARAM
|
||||||
|
SNR_SCHED_SETSCHEDULER ScmpSyscall = SYS_SCHED_SETSCHEDULER
|
||||||
|
SNR_SCHED_GETSCHEDULER ScmpSyscall = SYS_SCHED_GETSCHEDULER
|
||||||
|
SNR_SCHED_GETPARAM ScmpSyscall = SYS_SCHED_GETPARAM
|
||||||
|
SNR_SCHED_SETAFFINITY ScmpSyscall = SYS_SCHED_SETAFFINITY
|
||||||
|
SNR_SCHED_GETAFFINITY ScmpSyscall = SYS_SCHED_GETAFFINITY
|
||||||
|
SNR_SCHED_YIELD ScmpSyscall = SYS_SCHED_YIELD
|
||||||
|
SNR_SCHED_GET_PRIORITY_MAX ScmpSyscall = SYS_SCHED_GET_PRIORITY_MAX
|
||||||
|
SNR_SCHED_GET_PRIORITY_MIN ScmpSyscall = SYS_SCHED_GET_PRIORITY_MIN
|
||||||
|
SNR_SCHED_RR_GET_INTERVAL ScmpSyscall = SYS_SCHED_RR_GET_INTERVAL
|
||||||
|
SNR_RESTART_SYSCALL ScmpSyscall = SYS_RESTART_SYSCALL
|
||||||
|
SNR_KILL ScmpSyscall = SYS_KILL
|
||||||
|
SNR_TKILL ScmpSyscall = SYS_TKILL
|
||||||
|
SNR_TGKILL ScmpSyscall = SYS_TGKILL
|
||||||
|
SNR_SIGALTSTACK ScmpSyscall = SYS_SIGALTSTACK
|
||||||
|
SNR_RT_SIGSUSPEND ScmpSyscall = SYS_RT_SIGSUSPEND
|
||||||
|
SNR_RT_SIGACTION ScmpSyscall = SYS_RT_SIGACTION
|
||||||
|
SNR_RT_SIGPROCMASK ScmpSyscall = SYS_RT_SIGPROCMASK
|
||||||
|
SNR_RT_SIGPENDING ScmpSyscall = SYS_RT_SIGPENDING
|
||||||
|
SNR_RT_SIGTIMEDWAIT ScmpSyscall = SYS_RT_SIGTIMEDWAIT
|
||||||
|
SNR_RT_SIGQUEUEINFO ScmpSyscall = SYS_RT_SIGQUEUEINFO
|
||||||
|
SNR_RT_SIGRETURN ScmpSyscall = SYS_RT_SIGRETURN
|
||||||
|
SNR_SETPRIORITY ScmpSyscall = SYS_SETPRIORITY
|
||||||
|
SNR_GETPRIORITY ScmpSyscall = SYS_GETPRIORITY
|
||||||
|
SNR_REBOOT ScmpSyscall = SYS_REBOOT
|
||||||
|
SNR_SETREGID ScmpSyscall = SYS_SETREGID
|
||||||
|
SNR_SETGID ScmpSyscall = SYS_SETGID
|
||||||
|
SNR_SETREUID ScmpSyscall = SYS_SETREUID
|
||||||
|
SNR_SETUID ScmpSyscall = SYS_SETUID
|
||||||
|
SNR_SETRESUID ScmpSyscall = SYS_SETRESUID
|
||||||
|
SNR_GETRESUID ScmpSyscall = SYS_GETRESUID
|
||||||
|
SNR_SETRESGID ScmpSyscall = SYS_SETRESGID
|
||||||
|
SNR_GETRESGID ScmpSyscall = SYS_GETRESGID
|
||||||
|
SNR_SETFSUID ScmpSyscall = SYS_SETFSUID
|
||||||
|
SNR_SETFSGID ScmpSyscall = SYS_SETFSGID
|
||||||
|
SNR_TIMES ScmpSyscall = SYS_TIMES
|
||||||
|
SNR_SETPGID ScmpSyscall = SYS_SETPGID
|
||||||
|
SNR_GETPGID ScmpSyscall = SYS_GETPGID
|
||||||
|
SNR_GETSID ScmpSyscall = SYS_GETSID
|
||||||
|
SNR_SETSID ScmpSyscall = SYS_SETSID
|
||||||
|
SNR_GETGROUPS ScmpSyscall = SYS_GETGROUPS
|
||||||
|
SNR_SETGROUPS ScmpSyscall = SYS_SETGROUPS
|
||||||
|
SNR_UNAME ScmpSyscall = SYS_UNAME
|
||||||
|
SNR_SETHOSTNAME ScmpSyscall = SYS_SETHOSTNAME
|
||||||
|
SNR_SETDOMAINNAME ScmpSyscall = SYS_SETDOMAINNAME
|
||||||
|
SNR_GETRLIMIT ScmpSyscall = SYS_GETRLIMIT
|
||||||
|
SNR_SETRLIMIT ScmpSyscall = SYS_SETRLIMIT
|
||||||
|
SNR_GETRUSAGE ScmpSyscall = SYS_GETRUSAGE
|
||||||
|
SNR_UMASK ScmpSyscall = SYS_UMASK
|
||||||
|
SNR_PRCTL ScmpSyscall = SYS_PRCTL
|
||||||
|
SNR_GETCPU ScmpSyscall = SYS_GETCPU
|
||||||
|
SNR_GETTIMEOFDAY ScmpSyscall = SYS_GETTIMEOFDAY
|
||||||
|
SNR_SETTIMEOFDAY ScmpSyscall = SYS_SETTIMEOFDAY
|
||||||
|
SNR_ADJTIMEX ScmpSyscall = SYS_ADJTIMEX
|
||||||
|
SNR_GETPID ScmpSyscall = SYS_GETPID
|
||||||
|
SNR_GETPPID ScmpSyscall = SYS_GETPPID
|
||||||
|
SNR_GETUID ScmpSyscall = SYS_GETUID
|
||||||
|
SNR_GETEUID ScmpSyscall = SYS_GETEUID
|
||||||
|
SNR_GETGID ScmpSyscall = SYS_GETGID
|
||||||
|
SNR_GETEGID ScmpSyscall = SYS_GETEGID
|
||||||
|
SNR_GETTID ScmpSyscall = SYS_GETTID
|
||||||
|
SNR_SYSINFO ScmpSyscall = SYS_SYSINFO
|
||||||
|
SNR_MQ_OPEN ScmpSyscall = SYS_MQ_OPEN
|
||||||
|
SNR_MQ_UNLINK ScmpSyscall = SYS_MQ_UNLINK
|
||||||
|
SNR_MQ_TIMEDSEND ScmpSyscall = SYS_MQ_TIMEDSEND
|
||||||
|
SNR_MQ_TIMEDRECEIVE ScmpSyscall = SYS_MQ_TIMEDRECEIVE
|
||||||
|
SNR_MQ_NOTIFY ScmpSyscall = SYS_MQ_NOTIFY
|
||||||
|
SNR_MQ_GETSETATTR ScmpSyscall = SYS_MQ_GETSETATTR
|
||||||
|
SNR_MSGGET ScmpSyscall = SYS_MSGGET
|
||||||
|
SNR_MSGCTL ScmpSyscall = SYS_MSGCTL
|
||||||
|
SNR_MSGRCV ScmpSyscall = SYS_MSGRCV
|
||||||
|
SNR_MSGSND ScmpSyscall = SYS_MSGSND
|
||||||
|
SNR_SEMGET ScmpSyscall = SYS_SEMGET
|
||||||
|
SNR_SEMCTL ScmpSyscall = SYS_SEMCTL
|
||||||
|
SNR_SEMTIMEDOP ScmpSyscall = SYS_SEMTIMEDOP
|
||||||
|
SNR_SEMOP ScmpSyscall = SYS_SEMOP
|
||||||
|
SNR_SHMGET ScmpSyscall = SYS_SHMGET
|
||||||
|
SNR_SHMCTL ScmpSyscall = SYS_SHMCTL
|
||||||
|
SNR_SHMAT ScmpSyscall = SYS_SHMAT
|
||||||
|
SNR_SHMDT ScmpSyscall = SYS_SHMDT
|
||||||
|
SNR_SOCKET ScmpSyscall = SYS_SOCKET
|
||||||
|
SNR_SOCKETPAIR ScmpSyscall = SYS_SOCKETPAIR
|
||||||
|
SNR_BIND ScmpSyscall = SYS_BIND
|
||||||
|
SNR_LISTEN ScmpSyscall = SYS_LISTEN
|
||||||
|
SNR_ACCEPT ScmpSyscall = SYS_ACCEPT
|
||||||
|
SNR_CONNECT ScmpSyscall = SYS_CONNECT
|
||||||
|
SNR_GETSOCKNAME ScmpSyscall = SYS_GETSOCKNAME
|
||||||
|
SNR_GETPEERNAME ScmpSyscall = SYS_GETPEERNAME
|
||||||
|
SNR_SENDTO ScmpSyscall = SYS_SENDTO
|
||||||
|
SNR_RECVFROM ScmpSyscall = SYS_RECVFROM
|
||||||
|
SNR_SETSOCKOPT ScmpSyscall = SYS_SETSOCKOPT
|
||||||
|
SNR_GETSOCKOPT ScmpSyscall = SYS_GETSOCKOPT
|
||||||
|
SNR_SHUTDOWN ScmpSyscall = SYS_SHUTDOWN
|
||||||
|
SNR_SENDMSG ScmpSyscall = SYS_SENDMSG
|
||||||
|
SNR_RECVMSG ScmpSyscall = SYS_RECVMSG
|
||||||
|
SNR_READAHEAD ScmpSyscall = SYS_READAHEAD
|
||||||
|
SNR_BRK ScmpSyscall = SYS_BRK
|
||||||
|
SNR_MUNMAP ScmpSyscall = SYS_MUNMAP
|
||||||
|
SNR_MREMAP ScmpSyscall = SYS_MREMAP
|
||||||
|
SNR_ADD_KEY ScmpSyscall = SYS_ADD_KEY
|
||||||
|
SNR_REQUEST_KEY ScmpSyscall = SYS_REQUEST_KEY
|
||||||
|
SNR_KEYCTL ScmpSyscall = SYS_KEYCTL
|
||||||
|
SNR_CLONE ScmpSyscall = SYS_CLONE
|
||||||
|
SNR_EXECVE ScmpSyscall = SYS_EXECVE
|
||||||
|
SNR_MMAP ScmpSyscall = SYS_MMAP
|
||||||
|
SNR_FADVISE64 ScmpSyscall = SYS_FADVISE64
|
||||||
|
SNR_SWAPON ScmpSyscall = SYS_SWAPON
|
||||||
|
SNR_SWAPOFF ScmpSyscall = SYS_SWAPOFF
|
||||||
|
SNR_MPROTECT ScmpSyscall = SYS_MPROTECT
|
||||||
|
SNR_MSYNC ScmpSyscall = SYS_MSYNC
|
||||||
|
SNR_MLOCK ScmpSyscall = SYS_MLOCK
|
||||||
|
SNR_MUNLOCK ScmpSyscall = SYS_MUNLOCK
|
||||||
|
SNR_MLOCKALL ScmpSyscall = SYS_MLOCKALL
|
||||||
|
SNR_MUNLOCKALL ScmpSyscall = SYS_MUNLOCKALL
|
||||||
|
SNR_MINCORE ScmpSyscall = SYS_MINCORE
|
||||||
|
SNR_MADVISE ScmpSyscall = SYS_MADVISE
|
||||||
|
SNR_REMAP_FILE_PAGES ScmpSyscall = SYS_REMAP_FILE_PAGES
|
||||||
|
SNR_MBIND ScmpSyscall = SYS_MBIND
|
||||||
|
SNR_GET_MEMPOLICY ScmpSyscall = SYS_GET_MEMPOLICY
|
||||||
|
SNR_SET_MEMPOLICY ScmpSyscall = SYS_SET_MEMPOLICY
|
||||||
|
SNR_MIGRATE_PAGES ScmpSyscall = SYS_MIGRATE_PAGES
|
||||||
|
SNR_MOVE_PAGES ScmpSyscall = SYS_MOVE_PAGES
|
||||||
|
SNR_RT_TGSIGQUEUEINFO ScmpSyscall = SYS_RT_TGSIGQUEUEINFO
|
||||||
|
SNR_PERF_EVENT_OPEN ScmpSyscall = SYS_PERF_EVENT_OPEN
|
||||||
|
SNR_ACCEPT4 ScmpSyscall = SYS_ACCEPT4
|
||||||
|
SNR_RECVMMSG ScmpSyscall = SYS_RECVMMSG
|
||||||
|
SNR_WAIT4 ScmpSyscall = SYS_WAIT4
|
||||||
|
SNR_PRLIMIT64 ScmpSyscall = SYS_PRLIMIT64
|
||||||
|
SNR_FANOTIFY_INIT ScmpSyscall = SYS_FANOTIFY_INIT
|
||||||
|
SNR_FANOTIFY_MARK ScmpSyscall = SYS_FANOTIFY_MARK
|
||||||
|
SNR_NAME_TO_HANDLE_AT ScmpSyscall = SYS_NAME_TO_HANDLE_AT
|
||||||
|
SNR_OPEN_BY_HANDLE_AT ScmpSyscall = SYS_OPEN_BY_HANDLE_AT
|
||||||
|
SNR_CLOCK_ADJTIME ScmpSyscall = SYS_CLOCK_ADJTIME
|
||||||
|
SNR_SYNCFS ScmpSyscall = SYS_SYNCFS
|
||||||
|
SNR_SETNS ScmpSyscall = SYS_SETNS
|
||||||
|
SNR_SENDMMSG ScmpSyscall = SYS_SENDMMSG
|
||||||
|
SNR_PROCESS_VM_READV ScmpSyscall = SYS_PROCESS_VM_READV
|
||||||
|
SNR_PROCESS_VM_WRITEV ScmpSyscall = SYS_PROCESS_VM_WRITEV
|
||||||
|
SNR_KCMP ScmpSyscall = SYS_KCMP
|
||||||
|
SNR_FINIT_MODULE ScmpSyscall = SYS_FINIT_MODULE
|
||||||
|
SNR_SCHED_SETATTR ScmpSyscall = SYS_SCHED_SETATTR
|
||||||
|
SNR_SCHED_GETATTR ScmpSyscall = SYS_SCHED_GETATTR
|
||||||
|
SNR_RENAMEAT2 ScmpSyscall = SYS_RENAMEAT2
|
||||||
|
SNR_SECCOMP ScmpSyscall = SYS_SECCOMP
|
||||||
|
SNR_GETRANDOM ScmpSyscall = SYS_GETRANDOM
|
||||||
|
SNR_MEMFD_CREATE ScmpSyscall = SYS_MEMFD_CREATE
|
||||||
|
SNR_BPF ScmpSyscall = SYS_BPF
|
||||||
|
SNR_EXECVEAT ScmpSyscall = SYS_EXECVEAT
|
||||||
|
SNR_USERFAULTFD ScmpSyscall = SYS_USERFAULTFD
|
||||||
|
SNR_MEMBARRIER ScmpSyscall = SYS_MEMBARRIER
|
||||||
|
SNR_MLOCK2 ScmpSyscall = SYS_MLOCK2
|
||||||
|
SNR_COPY_FILE_RANGE ScmpSyscall = SYS_COPY_FILE_RANGE
|
||||||
|
SNR_PREADV2 ScmpSyscall = SYS_PREADV2
|
||||||
|
SNR_PWRITEV2 ScmpSyscall = SYS_PWRITEV2
|
||||||
|
SNR_PKEY_MPROTECT ScmpSyscall = SYS_PKEY_MPROTECT
|
||||||
|
SNR_PKEY_ALLOC ScmpSyscall = SYS_PKEY_ALLOC
|
||||||
|
SNR_PKEY_FREE ScmpSyscall = SYS_PKEY_FREE
|
||||||
|
SNR_STATX ScmpSyscall = SYS_STATX
|
||||||
|
SNR_IO_PGETEVENTS ScmpSyscall = SYS_IO_PGETEVENTS
|
||||||
|
SNR_RSEQ ScmpSyscall = SYS_RSEQ
|
||||||
|
SNR_KEXEC_FILE_LOAD ScmpSyscall = SYS_KEXEC_FILE_LOAD
|
||||||
|
SNR_PIDFD_SEND_SIGNAL ScmpSyscall = SYS_PIDFD_SEND_SIGNAL
|
||||||
|
SNR_IO_URING_SETUP ScmpSyscall = SYS_IO_URING_SETUP
|
||||||
|
SNR_IO_URING_ENTER ScmpSyscall = SYS_IO_URING_ENTER
|
||||||
|
SNR_IO_URING_REGISTER ScmpSyscall = SYS_IO_URING_REGISTER
|
||||||
|
SNR_OPEN_TREE ScmpSyscall = SYS_OPEN_TREE
|
||||||
|
SNR_MOVE_MOUNT ScmpSyscall = SYS_MOVE_MOUNT
|
||||||
|
SNR_FSOPEN ScmpSyscall = SYS_FSOPEN
|
||||||
|
SNR_FSCONFIG ScmpSyscall = SYS_FSCONFIG
|
||||||
|
SNR_FSMOUNT ScmpSyscall = SYS_FSMOUNT
|
||||||
|
SNR_FSPICK ScmpSyscall = SYS_FSPICK
|
||||||
|
SNR_PIDFD_OPEN ScmpSyscall = SYS_PIDFD_OPEN
|
||||||
|
SNR_CLONE3 ScmpSyscall = SYS_CLONE3
|
||||||
|
SNR_CLOSE_RANGE ScmpSyscall = SYS_CLOSE_RANGE
|
||||||
|
SNR_OPENAT2 ScmpSyscall = SYS_OPENAT2
|
||||||
|
SNR_PIDFD_GETFD ScmpSyscall = SYS_PIDFD_GETFD
|
||||||
|
SNR_FACCESSAT2 ScmpSyscall = SYS_FACCESSAT2
|
||||||
|
SNR_PROCESS_MADVISE ScmpSyscall = SYS_PROCESS_MADVISE
|
||||||
|
SNR_EPOLL_PWAIT2 ScmpSyscall = SYS_EPOLL_PWAIT2
|
||||||
|
SNR_MOUNT_SETATTR ScmpSyscall = SYS_MOUNT_SETATTR
|
||||||
|
SNR_QUOTACTL_FD ScmpSyscall = SYS_QUOTACTL_FD
|
||||||
|
SNR_LANDLOCK_CREATE_RULESET ScmpSyscall = SYS_LANDLOCK_CREATE_RULESET
|
||||||
|
SNR_LANDLOCK_ADD_RULE ScmpSyscall = SYS_LANDLOCK_ADD_RULE
|
||||||
|
SNR_LANDLOCK_RESTRICT_SELF ScmpSyscall = SYS_LANDLOCK_RESTRICT_SELF
|
||||||
|
SNR_MEMFD_SECRET ScmpSyscall = SYS_MEMFD_SECRET
|
||||||
|
SNR_PROCESS_MRELEASE ScmpSyscall = SYS_PROCESS_MRELEASE
|
||||||
|
SNR_FUTEX_WAITV ScmpSyscall = SYS_FUTEX_WAITV
|
||||||
|
SNR_SET_MEMPOLICY_HOME_NODE ScmpSyscall = SYS_SET_MEMPOLICY_HOME_NODE
|
||||||
|
SNR_CACHESTAT ScmpSyscall = SYS_CACHESTAT
|
||||||
|
SNR_FCHMODAT2 ScmpSyscall = SYS_FCHMODAT2
|
||||||
|
SNR_MAP_SHADOW_STACK ScmpSyscall = SYS_MAP_SHADOW_STACK
|
||||||
|
SNR_FUTEX_WAKE ScmpSyscall = SYS_FUTEX_WAKE
|
||||||
|
SNR_FUTEX_WAIT ScmpSyscall = SYS_FUTEX_WAIT
|
||||||
|
SNR_FUTEX_REQUEUE ScmpSyscall = SYS_FUTEX_REQUEUE
|
||||||
|
SNR_STATMOUNT ScmpSyscall = SYS_STATMOUNT
|
||||||
|
SNR_LISTMOUNT ScmpSyscall = SYS_LISTMOUNT
|
||||||
|
SNR_LSM_GET_SELF_ATTR ScmpSyscall = SYS_LSM_GET_SELF_ATTR
|
||||||
|
SNR_LSM_SET_SELF_ATTR ScmpSyscall = SYS_LSM_SET_SELF_ATTR
|
||||||
|
SNR_LSM_LIST_MODULES ScmpSyscall = SYS_LSM_LIST_MODULES
|
||||||
|
SNR_MSEAL ScmpSyscall = SYS_MSEAL
|
||||||
|
)
|
||||||
|
|||||||
@ -2,13 +2,15 @@ package stub_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Made available here to check panic recovery behaviour.
|
||||||
|
//
|
||||||
//go:linkname handleExitNew hakurei.app/container/stub.handleExitNew
|
//go:linkname handleExitNew hakurei.app/container/stub.handleExitNew
|
||||||
func handleExitNew(_ testing.TB)
|
func handleExitNew(t testing.TB)
|
||||||
|
|
||||||
// overrideTFailNow overrides the Fail and FailNow method.
|
// overrideTFailNow overrides the Fail and FailNow method.
|
||||||
type overrideTFailNow struct {
|
type overrideTFailNow struct {
|
||||||
|
|||||||
6
dist/release.sh
vendored
6
dist/release.sh
vendored
@ -10,9 +10,9 @@ cp -rv "dist/comp" "${out}"
|
|||||||
|
|
||||||
go generate ./...
|
go generate ./...
|
||||||
go build -trimpath -v -o "${out}/bin/" -ldflags "-s -w -buildid= -extldflags '-static'
|
go build -trimpath -v -o "${out}/bin/" -ldflags "-s -w -buildid= -extldflags '-static'
|
||||||
-X hakurei.app/internal.buildVersion=${VERSION}
|
-X hakurei.app/internal/info.buildVersion=${VERSION}
|
||||||
-X hakurei.app/internal.hakureiPath=/usr/bin/hakurei
|
-X hakurei.app/internal/info.hakureiPath=/usr/bin/hakurei
|
||||||
-X hakurei.app/internal.hsuPath=/usr/bin/hsu
|
-X hakurei.app/internal/info.hsuPath=/usr/bin/hsu
|
||||||
-X main.hakureiPath=/usr/bin/hakurei" ./...
|
-X main.hakureiPath=/usr/bin/hakurei" ./...
|
||||||
|
|
||||||
rm -f "./${out}.tar.gz" && tar -C dist -czf "${out}.tar.gz" "${pname}"
|
rm -f "./${out}.tar.gz" && tar -C dist -czf "${out}.tar.gz" "${pname}"
|
||||||
|
|||||||
@ -114,7 +114,7 @@
|
|||||||
inherit (pkgs)
|
inherit (pkgs)
|
||||||
# passthru.buildInputs
|
# passthru.buildInputs
|
||||||
go
|
go
|
||||||
gcc
|
clang
|
||||||
|
|
||||||
# nativeBuildInputs
|
# nativeBuildInputs
|
||||||
pkg-config
|
pkg-config
|
||||||
@ -129,6 +129,10 @@
|
|||||||
zstd
|
zstd
|
||||||
gnutar
|
gnutar
|
||||||
coreutils
|
coreutils
|
||||||
|
|
||||||
|
# for check
|
||||||
|
util-linux
|
||||||
|
nettools
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
hsu = pkgs.callPackage ./cmd/hsu/package.nix { inherit (self.packages.${system}) hakurei; };
|
hsu = pkgs.callPackage ./cmd/hsu/package.nix { inherit (self.packages.${system}) hakurei; };
|
||||||
@ -144,7 +148,7 @@
|
|||||||
&& chmod -R +w .
|
&& chmod -R +w .
|
||||||
|
|
||||||
export HAKUREI_VERSION="v${hakurei.version}"
|
export HAKUREI_VERSION="v${hakurei.version}"
|
||||||
./dist/release.sh && mkdir $out && cp -v "dist/hakurei-$HAKUREI_VERSION.tar.gz"* $out
|
CC="clang -O3 -Werror" ./dist/release.sh && mkdir $out && cp -v "dist/hakurei-$HAKUREI_VERSION.tar.gz"* $out
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
73
helper/deprecated.go
Normal file
73
helper/deprecated.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Package helper exposes the internal/helper package.
|
||||||
|
//
|
||||||
|
// Deprecated: This package will be removed in 0.4.
|
||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"time"
|
||||||
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
|
"hakurei.app/container/check"
|
||||||
|
"hakurei.app/internal/helper"
|
||||||
|
"hakurei.app/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:linkname WaitDelay hakurei.app/internal/helper.WaitDelay
|
||||||
|
var WaitDelay time.Duration
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HakureiHelper is set to 1 when args fd is enabled and 0 otherwise.
|
||||||
|
HakureiHelper = helper.HakureiHelper
|
||||||
|
// HakureiStatus is set to 1 when stat fd is enabled and 0 otherwise.
|
||||||
|
HakureiStatus = helper.HakureiStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
type Helper = helper.Helper
|
||||||
|
|
||||||
|
// NewCheckedArgs returns a checked null-terminated argument writer for a copy of args.
|
||||||
|
//
|
||||||
|
//go:linkname NewCheckedArgs hakurei.app/internal/helper.NewCheckedArgs
|
||||||
|
func NewCheckedArgs(args ...string) (wt io.WriterTo, err error)
|
||||||
|
|
||||||
|
// MustNewCheckedArgs returns a checked null-terminated argument writer for a copy of args.
|
||||||
|
// If s contains a NUL byte this function panics instead of returning an error.
|
||||||
|
//
|
||||||
|
//go:linkname MustNewCheckedArgs hakurei.app/internal/helper.MustNewCheckedArgs
|
||||||
|
func MustNewCheckedArgs(args ...string) io.WriterTo
|
||||||
|
|
||||||
|
// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
|
||||||
|
// Function argF returns an array of arguments passed directly to the child process.
|
||||||
|
//
|
||||||
|
//go:linkname NewDirect hakurei.app/internal/helper.NewDirect
|
||||||
|
func NewDirect(
|
||||||
|
ctx context.Context,
|
||||||
|
name string,
|
||||||
|
wt io.WriterTo,
|
||||||
|
stat bool,
|
||||||
|
argF func(argsFd, statFd int) []string,
|
||||||
|
cmdF func(cmd *exec.Cmd),
|
||||||
|
extraFiles []*os.File,
|
||||||
|
) Helper
|
||||||
|
|
||||||
|
// New initialises a Helper instance with wt as the null-terminated argument writer.
|
||||||
|
//
|
||||||
|
//go:linkname New hakurei.app/internal/helper.New
|
||||||
|
func New(
|
||||||
|
ctx context.Context,
|
||||||
|
msg message.Msg,
|
||||||
|
pathname *check.Absolute, name string,
|
||||||
|
wt io.WriterTo,
|
||||||
|
stat bool,
|
||||||
|
argF func(argsFd, statFd int) []string,
|
||||||
|
cmdF func(z *container.Container),
|
||||||
|
extraFiles []*os.File,
|
||||||
|
) Helper
|
||||||
|
|
||||||
|
// InternalHelperStub is an internal function but exported because it is cross-package;
|
||||||
|
// it is part of the implementation of the helper stub.
|
||||||
|
func InternalHelperStub() { helper.InternalHelperStub() }
|
||||||
63
helper/proc/deprecated.go
Normal file
63
helper/proc/deprecated.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Deprecated: This package will be removed in 0.4.
|
||||||
|
package proc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"time"
|
||||||
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
"hakurei.app/internal/helper/proc"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:linkname FulfillmentTimeout hakurei.app/internal/helper/proc.FulfillmentTimeout
|
||||||
|
var FulfillmentTimeout time.Duration
|
||||||
|
|
||||||
|
// A File is an extra file with deferred initialisation.
|
||||||
|
type File = proc.File
|
||||||
|
|
||||||
|
// ExtraFilesPre is a linked list storing addresses of [os.File].
|
||||||
|
type ExtraFilesPre = proc.ExtraFilesPre
|
||||||
|
|
||||||
|
// Fulfill calls the [File.Fulfill] method on all files, starts cmd and blocks until all fulfillment completes.
|
||||||
|
//
|
||||||
|
//go:linkname Fulfill hakurei.app/internal/helper/proc.Fulfill
|
||||||
|
func Fulfill(ctx context.Context,
|
||||||
|
v *[]*os.File, start func() error,
|
||||||
|
files []File, extraFiles *ExtraFilesPre,
|
||||||
|
) (err error)
|
||||||
|
|
||||||
|
// InitFile initialises f as part of the slice extraFiles points to,
|
||||||
|
// and returns its final fd value.
|
||||||
|
//
|
||||||
|
//go:linkname InitFile hakurei.app/internal/helper/proc.InitFile
|
||||||
|
func InitFile(f File, extraFiles *ExtraFilesPre) (fd uintptr)
|
||||||
|
|
||||||
|
// BaseFile implements the Init method of the File interface and provides indirect access to extra file state.
|
||||||
|
type BaseFile = proc.BaseFile
|
||||||
|
|
||||||
|
//go:linkname ExtraFile hakurei.app/internal/helper/proc.ExtraFile
|
||||||
|
func ExtraFile(cmd *exec.Cmd, f *os.File) (fd uintptr)
|
||||||
|
|
||||||
|
//go:linkname ExtraFileSlice hakurei.app/internal/helper/proc.ExtraFileSlice
|
||||||
|
func ExtraFileSlice(extraFiles *[]*os.File, f *os.File) (fd uintptr)
|
||||||
|
|
||||||
|
// NewWriterTo returns a [File] that receives content from wt on fulfillment.
|
||||||
|
//
|
||||||
|
//go:linkname NewWriterTo hakurei.app/internal/helper/proc.NewWriterTo
|
||||||
|
func NewWriterTo(wt io.WriterTo) File
|
||||||
|
|
||||||
|
// NewStat returns a [File] implementing the behaviour
|
||||||
|
// of the receiving end of xdg-dbus-proxy stat fd.
|
||||||
|
//
|
||||||
|
//go:linkname NewStat hakurei.app/internal/helper/proc.NewStat
|
||||||
|
func NewStat(s *io.Closer) File
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:linkname ErrStatFault hakurei.app/internal/helper/proc.ErrStatFault
|
||||||
|
ErrStatFault error
|
||||||
|
//go:linkname ErrStatRead hakurei.app/internal/helper/proc.ErrStatRead
|
||||||
|
ErrStatRead error
|
||||||
|
)
|
||||||
@ -6,11 +6,13 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Made available here to check time encoding behaviour of [hst.ID].
|
||||||
|
//
|
||||||
//go:linkname newInstanceID hakurei.app/hst.newInstanceID
|
//go:linkname newInstanceID hakurei.app/hst.newInstanceID
|
||||||
func newInstanceID(id *hst.ID, p uint64) error
|
func newInstanceID(id *hst.ID, p uint64) error
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testFileName = "acl.test"
|
const testFileName = "acl.test"
|
||||||
90
internal/acl/libacl-helper.c
Normal file
90
internal/acl/libacl-helper.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "libacl-helper.h"
|
||||||
|
#include <acl/libacl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/acl.h>
|
||||||
|
|
||||||
|
int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
|
||||||
|
acl_perm_t *perms, size_t plen) {
|
||||||
|
int ret;
|
||||||
|
bool v;
|
||||||
|
int i;
|
||||||
|
acl_t acl;
|
||||||
|
acl_entry_t entry;
|
||||||
|
acl_tag_t tag_type;
|
||||||
|
void *qualifier_p;
|
||||||
|
acl_permset_t permset;
|
||||||
|
|
||||||
|
ret = -1; /* acl_get_file */
|
||||||
|
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
|
||||||
|
if (acl == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* prune entries by uid */
|
||||||
|
for (i = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); i == 1;
|
||||||
|
i = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
|
||||||
|
ret = -2; /* acl_get_tag_type */
|
||||||
|
if (acl_get_tag_type(entry, &tag_type) != 0)
|
||||||
|
goto out;
|
||||||
|
if (tag_type != ACL_USER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = -3; /* acl_get_qualifier */
|
||||||
|
qualifier_p = acl_get_qualifier(entry);
|
||||||
|
if (qualifier_p == NULL)
|
||||||
|
goto out;
|
||||||
|
v = *(uid_t *)qualifier_p == uid;
|
||||||
|
acl_free(qualifier_p);
|
||||||
|
|
||||||
|
if (!v)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = -4; /* acl_delete_entry */
|
||||||
|
if (acl_delete_entry(acl, entry) != 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plen == 0)
|
||||||
|
goto set;
|
||||||
|
|
||||||
|
ret = -5; /* acl_create_entry */
|
||||||
|
if (acl_create_entry(&acl, &entry) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -6; /* acl_get_permset */
|
||||||
|
if (acl_get_permset(entry, &permset) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -7; /* acl_add_perm */
|
||||||
|
for (i = 0; i < plen; i++) {
|
||||||
|
if (acl_add_perm(permset, perms[i]) != 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = -8; /* acl_set_tag_type */
|
||||||
|
if (acl_set_tag_type(entry, ACL_USER) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -9; /* acl_set_qualifier */
|
||||||
|
if (acl_set_qualifier(entry, (void *)&uid) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
set:
|
||||||
|
ret = -10; /* acl_calc_mask */
|
||||||
|
if (acl_calc_mask(&acl) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -11; /* acl_valid */
|
||||||
|
if (acl_valid(acl) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -12; /* acl_set_file */
|
||||||
|
if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) == 0)
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free((void *)path_p);
|
||||||
|
if (acl != NULL)
|
||||||
|
acl_free((void *)acl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ package acl_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPerms(t *testing.T) {
|
func TestPerms(t *testing.T) {
|
||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/internal/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/internal/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConfigArgs(t *testing.T) {
|
func TestConfigArgs(t *testing.T) {
|
||||||
@ -11,9 +11,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/dbus"
|
||||||
|
"hakurei.app/internal/helper"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFinalise(t *testing.T) {
|
func TestFinalise(t *testing.T) {
|
||||||
@ -12,7 +12,7 @@ import (
|
|||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
"hakurei.app/ldd"
|
"hakurei.app/ldd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ func (p *Proxy) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var libPaths []*check.Absolute
|
var libPaths []*check.Absolute
|
||||||
if entries, err := ldd.Exec(ctx, p.msg, toolPath.String()); err != nil {
|
if entries, err := ldd.Resolve(ctx, p.msg, toolPath); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
libPaths = ldd.Path(entries)
|
libPaths = ldd.Path(entries)
|
||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/helper"
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/helper"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestArgsString(t *testing.T) {
|
func TestArgsString(t *testing.T) {
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/helper/proc"
|
"hakurei.app/internal/helper/proc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
|
// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
|
||||||
@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCmd(t *testing.T) {
|
func TestCmd(t *testing.T) {
|
||||||
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/helper/proc"
|
"hakurei.app/internal/helper/proc"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ import (
|
|||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContainer(t *testing.T) {
|
func TestContainer(t *testing.T) {
|
||||||
@ -8,7 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/helper/proc"
|
"hakurei.app/internal/helper/proc"
|
||||||
)
|
)
|
||||||
|
|
||||||
var WaitDelay = 2 * time.Second
|
var WaitDelay = 2 * time.Second
|
||||||
@ -13,7 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package internal
|
package info
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package internal
|
package info
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package internal
|
package info
|
||||||
|
|
||||||
// FallbackVersion is returned when a version string was not set by the linker.
|
// FallbackVersion is returned when a version string was not set by the linker.
|
||||||
const FallbackVersion = "dirty"
|
const FallbackVersion = "dirty"
|
||||||
@ -14,9 +14,9 @@ import (
|
|||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal/dbus"
|
||||||
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// osFile represents [os.File].
|
// osFile represents [os.File].
|
||||||
@ -156,7 +156,7 @@ func (direct) seccompLoad(rules []std.NativeRule, flags seccomp.ExportFlag) erro
|
|||||||
return seccomp.Load(rules, flags)
|
return seccomp.Load(rules, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() }
|
func (direct) mustHsuPath() *check.Absolute { return info.MustHsuPath() }
|
||||||
|
|
||||||
func (direct) dbusAddress() (session, system string) { return dbus.Address() }
|
func (direct) dbusAddress() (session, system string) { return dbus.Address() }
|
||||||
|
|
||||||
|
|||||||
@ -24,8 +24,8 @@ import (
|
|||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// call initialises a [stub.Call].
|
// call initialises a [stub.Call].
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newWithMessage(msg string) error { return newWithMessageError(msg, os.ErrInvalid) }
|
func newWithMessage(msg string) error { return newWithMessageError(msg, os.ErrInvalid) }
|
||||||
@ -55,7 +55,7 @@ func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *hst.ID, con
|
|||||||
if errors.As(err, &unknownGroupError) {
|
if errors.As(err, &unknownGroupError) {
|
||||||
return newWithMessageError(fmt.Sprintf("unknown group %q", name), unknownGroupError)
|
return newWithMessageError(fmt.Sprintf("unknown group %q", name), unknownGroupError)
|
||||||
} else {
|
} else {
|
||||||
return &hst.AppError{Step: "look up group by name", Err: err}
|
return &hst.AppError{Step: "look up group by name", Err: err, Msg: err.Error()}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
supp[i] = gid
|
supp[i] = gid
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
package outcome
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"hakurei.app/hst"
|
|
||||||
"hakurei.app/message"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Main runs an app according to [hst.Config] and terminates. Main does not return.
|
|
||||||
func Main(ctx context.Context, msg message.Msg, config *hst.Config) {
|
|
||||||
var id hst.ID
|
|
||||||
if err := hst.NewInstanceID(&id); err != nil {
|
|
||||||
log.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
seal := outcome{syscallDispatcher: direct{msg}}
|
|
||||||
|
|
||||||
finaliseTime := time.Now()
|
|
||||||
if err := seal.finalise(ctx, msg, &id, config); err != nil {
|
|
||||||
printMessageError(msg.GetLogger().Fatalln, "cannot seal app:", err)
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
msg.Verbosef("finalise took %.2f ms", float64(time.Since(finaliseTime).Nanoseconds())/1e6)
|
|
||||||
|
|
||||||
seal.main(msg)
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
@ -9,10 +9,10 @@ import (
|
|||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/internal/env"
|
"hakurei.app/internal/env"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
"hakurei.app/system/acl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// envAllocSize is the initial size of the env map pre-allocated when the configured env map is nil.
|
// envAllocSize is the initial size of the env map pre-allocated when the configured env map is nil.
|
||||||
|
|||||||
@ -16,10 +16,10 @@ import (
|
|||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/internal/store"
|
"hakurei.app/internal/store"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -33,13 +33,13 @@ const (
|
|||||||
func NewStore(sc *hst.Paths) *store.Store { return store.New(sc.SharePath.Append("state")) }
|
func NewStore(sc *hst.Paths) *store.Store { return store.New(sc.SharePath.Append("state")) }
|
||||||
|
|
||||||
// main carries out outcome and terminates. main does not return.
|
// main carries out outcome and terminates. main does not return.
|
||||||
func (k *outcome) main(msg message.Msg) {
|
func (k *outcome) main(msg message.Msg, identifierFd int) {
|
||||||
if k.ctx == nil || k.sys == nil || k.state == nil {
|
if k.ctx == nil || k.sys == nil || k.state == nil {
|
||||||
panic("outcome: did not finalise")
|
panic("outcome: did not finalise")
|
||||||
}
|
}
|
||||||
|
|
||||||
// read comp value early for early failure
|
// read comp value early for early failure
|
||||||
hsuPath := internal.MustHsuPath()
|
hsuPath := info.MustHsuPath()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// transitions to processCommit, or processFinal on failure
|
// transitions to processCommit, or processFinal on failure
|
||||||
@ -163,6 +163,21 @@ func (k *outcome) main(msg message.Msg) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f := os.NewFile(uintptr(identifierFd), "identifier"); f != nil {
|
||||||
|
_, err = f.Write(k.state.id.v[:])
|
||||||
|
if err != nil {
|
||||||
|
unlock()
|
||||||
|
// transition here to avoid the commit/revert cycle on the doomed instance
|
||||||
|
perrorFatal(&hst.AppError{Step: "write instance identifier", Err: err},
|
||||||
|
"write instance identifier", processLifecycle)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msg.Verbosef("wrote identifier to %d", identifierFd)
|
||||||
|
if err = f.Close(); err != nil {
|
||||||
|
msg.Verbose(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = k.sys.Commit()
|
err = k.sys.Commit()
|
||||||
unlock()
|
unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
45
internal/outcome/run.go
Normal file
45
internal/outcome/run.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package outcome
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsPollDescriptor reports whether fd is the descriptor being used by the poller.
|
||||||
|
//
|
||||||
|
// Made available here to determine and reject impossible fd.
|
||||||
|
//
|
||||||
|
//go:linkname IsPollDescriptor internal/poll.IsPollDescriptor
|
||||||
|
func IsPollDescriptor(fd uintptr) bool
|
||||||
|
|
||||||
|
// Main runs an app according to [hst.Config] and terminates. Main does not return.
|
||||||
|
func Main(ctx context.Context, msg message.Msg, config *hst.Config, fd int) {
|
||||||
|
// avoids runtime internals or standard streams
|
||||||
|
if fd >= 0 {
|
||||||
|
if IsPollDescriptor(uintptr(fd)) || fd < 3 {
|
||||||
|
log.Fatalf("invalid identifier fd %d", fd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var id hst.ID
|
||||||
|
if err := hst.NewInstanceID(&id); err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
k := outcome{syscallDispatcher: direct{msg}}
|
||||||
|
|
||||||
|
finaliseTime := time.Now()
|
||||||
|
if err := k.finalise(ctx, msg, &id, config); err != nil {
|
||||||
|
printMessageError(msg.GetLogger().Fatalln, "cannot seal app:", err)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
msg.Verbosef("finalise took %.2f ms", float64(time.Since(finaliseTime).Nanoseconds())/1e6)
|
||||||
|
|
||||||
|
k.main(msg, fd)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
@ -21,10 +21,10 @@ import (
|
|||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/acl"
|
||||||
|
"hakurei.app/internal/dbus"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
"hakurei.app/system/acl"
|
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOutcomeMain(t *testing.T) {
|
func TestOutcomeMain(t *testing.T) {
|
||||||
@ -141,7 +141,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
Proc(fhs.AbsProc).
|
Proc(fhs.AbsProc).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
||||||
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
||||||
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777).
|
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
||||||
|
|
||||||
// spRuntimeOp
|
// spRuntimeOp
|
||||||
Tmpfs(fhs.AbsRunUser, 1<<12, 0755).
|
Tmpfs(fhs.AbsRunUser, 1<<12, 0755).
|
||||||
@ -243,7 +243,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
Proc(m("/proc/")).
|
Proc(m("/proc/")).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
||||||
DevWritable(m("/dev/"), true).
|
DevWritable(m("/dev/"), true).
|
||||||
Tmpfs(m("/dev/shm"), 0, 01777).
|
Tmpfs(m("/dev/shm/"), 0, 01777).
|
||||||
Tmpfs(m("/run/user/"), 4096, 0755).
|
Tmpfs(m("/run/user/"), 4096, 0755).
|
||||||
Bind(m("/tmp/hakurei.0/runtime/0"), m("/run/user/65534"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/runtime/0"), m("/run/user/65534"), std.BindWritable).
|
||||||
Bind(m("/tmp/hakurei.0/tmpdir/0"), m("/tmp/"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/tmpdir/0"), m("/tmp/"), std.BindWritable).
|
||||||
@ -412,7 +412,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
Proc(m("/proc/")).
|
Proc(m("/proc/")).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
||||||
DevWritable(m("/dev/"), true).
|
DevWritable(m("/dev/"), true).
|
||||||
Tmpfs(m("/dev/shm"), 0, 01777).
|
Tmpfs(m("/dev/shm/"), 0, 01777).
|
||||||
Tmpfs(m("/run/user/"), 4096, 0755).
|
Tmpfs(m("/run/user/"), 4096, 0755).
|
||||||
Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/65534"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/65534"), std.BindWritable).
|
||||||
Bind(m("/tmp/hakurei.0/tmpdir/9"), m("/tmp/"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/tmpdir/9"), m("/tmp/"), std.BindWritable).
|
||||||
@ -558,7 +558,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
Proc(m("/proc/")).
|
Proc(m("/proc/")).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
Tmpfs(hst.AbsPrivateTmp, 4096, 0755).
|
||||||
DevWritable(m("/dev/"), true).
|
DevWritable(m("/dev/"), true).
|
||||||
Tmpfs(m("/dev/shm"), 0, 01777).
|
Tmpfs(m("/dev/shm/"), 0, 01777).
|
||||||
Tmpfs(m("/run/user/"), 4096, 0755).
|
Tmpfs(m("/run/user/"), 4096, 0755).
|
||||||
Bind(m("/tmp/hakurei.0/runtime/1"), m("/run/user/1971"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/runtime/1"), m("/run/user/1971"), std.BindWritable).
|
||||||
Bind(m("/tmp/hakurei.0/tmpdir/1"), m("/tmp/"), std.BindWritable).
|
Bind(m("/tmp/hakurei.0/tmpdir/1"), m("/tmp/"), std.BindWritable).
|
||||||
@ -38,7 +38,7 @@ static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) {
|
|||||||
|
|
||||||
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd) {
|
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd) {
|
||||||
if (hakurei_shim_param_ppid != -1 || hakurei_shim_fd != -1)
|
if (hakurei_shim_param_ppid != -1 || hakurei_shim_fd != -1)
|
||||||
*(int *)NULL = 0; /* unreachable */
|
*(volatile int *)NULL = 0; /* unreachable */
|
||||||
|
|
||||||
struct sigaction new_action = {0}, old_action = {0};
|
struct sigaction new_action = {0}, old_action = {0};
|
||||||
if (sigaction(SIGCONT, NULL, &old_action) != 0)
|
if (sigaction(SIGCONT, NULL, &old_action) != 0)
|
||||||
|
|||||||
@ -66,7 +66,7 @@ func TestShimEntrypoint(t *testing.T) {
|
|||||||
Proc(fhs.AbsProc).
|
Proc(fhs.AbsProc).
|
||||||
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
||||||
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
||||||
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777).
|
Tmpfs(fhs.AbsDevShm, 0, 01777).
|
||||||
|
|
||||||
// spRuntimeOp
|
// spRuntimeOp
|
||||||
Tmpfs(fhs.AbsRunUser, 1<<12, 0755).
|
Tmpfs(fhs.AbsRunUser, 1<<12, 0755).
|
||||||
|
|||||||
@ -16,11 +16,11 @@ import (
|
|||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/acl"
|
||||||
|
"hakurei.app/internal/dbus"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/internal/validate"
|
"hakurei.app/internal/validate"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
"hakurei.app/system/acl"
|
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const varRunNscd = fhs.Var + "run/nscd"
|
const varRunNscd = fhs.Var + "run/nscd"
|
||||||
@ -116,7 +116,7 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error {
|
|||||||
state.params.Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice)
|
state.params.Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice)
|
||||||
}
|
}
|
||||||
// /dev is mounted readonly later on, this prevents /dev/shm from going readonly with it
|
// /dev is mounted readonly later on, this prevents /dev/shm from going readonly with it
|
||||||
state.params.Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777)
|
state.params.Tmpfs(fhs.AbsDevShm, 0, 01777)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,9 @@ import (
|
|||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/dbus"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpParamsOp(t *testing.T) {
|
func TestSpParamsOp(t *testing.T) {
|
||||||
@ -72,7 +72,7 @@ func TestSpParamsOp(t *testing.T) {
|
|||||||
Root(m("/var/lib/hakurei/base/org.debian"), std.BindWritable).
|
Root(m("/var/lib/hakurei/base/org.debian"), std.BindWritable).
|
||||||
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
||||||
DevWritable(fhs.AbsDev, true).
|
DevWritable(fhs.AbsDev, true).
|
||||||
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777),
|
Tmpfs(fhs.AbsDevShm, 0, 01777),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
"TERM": "xterm",
|
"TERM": "xterm",
|
||||||
}, func(t *testing.T, state *outcomeStateParams) {
|
}, func(t *testing.T, state *outcomeStateParams) {
|
||||||
@ -110,7 +110,7 @@ func TestSpParamsOp(t *testing.T) {
|
|||||||
Root(m("/var/lib/hakurei/base/org.debian"), std.BindWritable).
|
Root(m("/var/lib/hakurei/base/org.debian"), std.BindWritable).
|
||||||
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
|
||||||
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
Bind(fhs.AbsDev, fhs.AbsDev, std.BindWritable|std.BindDevice).
|
||||||
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777),
|
Tmpfs(fhs.AbsDevShm, 0, 01777),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
"TERM": "xterm",
|
"TERM": "xterm",
|
||||||
}, func(t *testing.T, state *outcomeStateParams) {
|
}, func(t *testing.T, state *outcomeStateParams) {
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/internal/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(spDBusOp)) }
|
func init() { gob.Register(new(spDBusOp)) }
|
||||||
|
|||||||
@ -6,12 +6,12 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/helper"
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/internal/acl"
|
||||||
|
"hakurei.app/internal/dbus"
|
||||||
|
"hakurei.app/internal/helper"
|
||||||
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
"hakurei.app/system"
|
|
||||||
"hakurei.app/system/acl"
|
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpDBusOp(t *testing.T) {
|
func TestSpDBusOp(t *testing.T) {
|
||||||
|
|||||||
@ -11,8 +11,8 @@ import (
|
|||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpPulseOp(t *testing.T) {
|
func TestSpPulseOp(t *testing.T) {
|
||||||
|
|||||||
@ -7,8 +7,8 @@ import (
|
|||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import (
|
|||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpRuntimeOp(t *testing.T) {
|
func TestSpRuntimeOp(t *testing.T) {
|
||||||
|
|||||||
@ -7,8 +7,8 @@ import (
|
|||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(spTmpdirOp{}) }
|
func init() { gob.Register(spTmpdirOp{}) }
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import (
|
|||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpTmpdirOp(t *testing.T) {
|
func TestSpTmpdirOp(t *testing.T) {
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/wayland"
|
"hakurei.app/internal/wayland"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(spWaylandOp)) }
|
func init() { gob.Register(new(spWaylandOp)) }
|
||||||
@ -25,8 +25,8 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error {
|
|||||||
|
|
||||||
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
|
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
|
||||||
var socketPath *check.Absolute
|
var socketPath *check.Absolute
|
||||||
if name, ok := state.k.lookupEnv(wayland.WaylandDisplay); !ok {
|
if name, ok := state.k.lookupEnv(wayland.Display); !ok {
|
||||||
state.msg.Verbose(wayland.WaylandDisplay + " is not set, assuming " + wayland.FallbackName)
|
state.msg.Verbose(wayland.Display + " is not set, assuming " + wayland.FallbackName)
|
||||||
socketPath = state.sc.RuntimePath.Append(wayland.FallbackName)
|
socketPath = state.sc.RuntimePath.Append(wayland.FallbackName)
|
||||||
} else if a, err := check.NewAbs(name); err != nil {
|
} else if a, err := check.NewAbs(name); err != nil {
|
||||||
socketPath = state.sc.RuntimePath.Append(name)
|
socketPath = state.sc.RuntimePath.Append(name)
|
||||||
@ -53,7 +53,7 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error {
|
|||||||
|
|
||||||
func (s *spWaylandOp) toContainer(state *outcomeStateParams) error {
|
func (s *spWaylandOp) toContainer(state *outcomeStateParams) error {
|
||||||
innerPath := state.runtimeDir.Append(wayland.FallbackName)
|
innerPath := state.runtimeDir.Append(wayland.FallbackName)
|
||||||
state.env[wayland.WaylandDisplay] = wayland.FallbackName
|
state.env[wayland.Display] = wayland.FallbackName
|
||||||
if s.SocketPath == nil {
|
if s.SocketPath == nil {
|
||||||
state.params.Bind(state.instancePath().Append("wayland"), innerPath, 0)
|
state.params.Bind(state.instancePath().Append("wayland"), innerPath, 0)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import (
|
|||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/internal/acl"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/system"
|
||||||
"hakurei.app/system/wayland"
|
"hakurei.app/internal/wayland"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpWaylandOp(t *testing.T) {
|
func TestSpWaylandOp(t *testing.T) {
|
||||||
@ -47,7 +47,7 @@ func TestSpWaylandOp(t *testing.T) {
|
|||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
|
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
wayland.WaylandDisplay: wayland.FallbackName,
|
wayland.Display: wayland.FallbackName,
|
||||||
}, nil), nil},
|
}, nil), nil},
|
||||||
|
|
||||||
{"success direct", func(isShim, _ bool) outcomeOp {
|
{"success direct", func(isShim, _ bool) outcomeOp {
|
||||||
@ -75,7 +75,7 @@ func TestSpWaylandOp(t *testing.T) {
|
|||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Bind(m("/proc/nonexistent/wayland"), m("/run/user/1000/wayland-0"), 0),
|
Bind(m("/proc/nonexistent/wayland"), m("/run/user/1000/wayland-0"), 0),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
wayland.WaylandDisplay: wayland.FallbackName,
|
wayland.Display: wayland.FallbackName,
|
||||||
}, nil), nil},
|
}, nil), nil},
|
||||||
|
|
||||||
{"success", func(bool, bool) outcomeOp {
|
{"success", func(bool, bool) outcomeOp {
|
||||||
@ -98,7 +98,7 @@ func TestSpWaylandOp(t *testing.T) {
|
|||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
|
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
|
||||||
}, paramsWantEnv(config, map[string]string{
|
}, paramsWantEnv(config, map[string]string{
|
||||||
wayland.WaylandDisplay: wayland.FallbackName,
|
wayland.Display: wayland.FallbackName,
|
||||||
}, nil), nil},
|
}, nil), nil},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import (
|
|||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
var absX11SocketDir = fhs.AbsTmp.Append(".X11-unix")
|
var absX11SocketDir = fhs.AbsTmp.Append(".X11-unix")
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/internal/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpX11Op(t *testing.T) {
|
func TestSpX11Op(t *testing.T) {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ func TestEntryData(t *testing.T) {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templateStateGob := mustEncodeGob(newTemplateState())
|
templateStateGob := mustEncodeGob(NewTemplateState())
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
@ -45,11 +45,11 @@ func TestEntryData(t *testing.T) {
|
|||||||
Step: "validate configuration", Err: hst.ErrConfigNull,
|
Step: "validate configuration", Err: hst.ErrConfigNull,
|
||||||
Msg: "invalid configuration"}},
|
Msg: "invalid configuration"}},
|
||||||
|
|
||||||
{"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, newTemplateState(), &hst.AppError{
|
{"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, NewTemplateState(), &hst.AppError{
|
||||||
Step: "validate state enablement", Err: os.ErrInvalid,
|
Step: "validate state enablement", Err: os.ErrInvalid,
|
||||||
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0xd, 0xff"}},
|
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0xd, 0xff"}},
|
||||||
|
|
||||||
{"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, newTemplateState(), nil},
|
{"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, NewTemplateState(), nil},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
@ -105,7 +105,7 @@ func TestEntryData(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("encode fault", func(t *testing.T) {
|
t.Run("encode fault", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
s := newTemplateState()
|
s := NewTemplateState()
|
||||||
|
|
||||||
t.Run("gob", func(t *testing.T) {
|
t.Run("gob", func(t *testing.T) {
|
||||||
var want = &hst.AppError{Step: "encode state body", Err: stub.UniqueError(0xcafe)}
|
var want = &hst.AppError{Step: "encode state body", Err: stub.UniqueError(0xcafe)}
|
||||||
@ -123,8 +123,8 @@ func TestEntryData(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTemplateState returns the address of a new template [hst.State] struct.
|
// NewTemplateState returns the address of a new template [hst.State] struct.
|
||||||
func newTemplateState() *hst.State {
|
func NewTemplateState() *hst.State {
|
||||||
return &hst.State{
|
return &hst.State{
|
||||||
ID: hst.ID(bytes.Repeat([]byte{0xaa}, len(hst.ID{}))),
|
ID: hst.ID(bytes.Repeat([]byte{0xaa}, len(hst.ID{}))),
|
||||||
PID: 0xcafe,
|
PID: 0xcafe,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
@ -18,18 +18,23 @@ import (
|
|||||||
"hakurei.app/internal/store"
|
"hakurei.app/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname newTemplateState hakurei.app/internal/store.newTemplateState
|
// Made available here for direct validation of state entry files.
|
||||||
func newTemplateState() *hst.State
|
//
|
||||||
|
|
||||||
//go:linkname entryDecode hakurei.app/internal/store.entryDecode
|
//go:linkname entryDecode hakurei.app/internal/store.entryDecode
|
||||||
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error)
|
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error)
|
||||||
|
|
||||||
|
// Made available here for direct access to known segment handles.
|
||||||
|
//
|
||||||
//go:linkname newHandle hakurei.app/internal/store.newHandle
|
//go:linkname newHandle hakurei.app/internal/store.newHandle
|
||||||
func newHandle(base *check.Absolute, identity int) *store.Handle
|
func newHandle(base *check.Absolute, identity int) *store.Handle
|
||||||
|
|
||||||
|
// Made available here to check open error handling behaviour.
|
||||||
|
//
|
||||||
//go:linkname open hakurei.app/internal/store.(*EntryHandle).open
|
//go:linkname open hakurei.app/internal/store.(*EntryHandle).open
|
||||||
func open(eh *store.EntryHandle, flag int, perm os.FileMode) (*os.File, error)
|
func open(eh *store.EntryHandle, flag int, perm os.FileMode) (*os.File, error)
|
||||||
|
|
||||||
|
// Made available here to check the saveload cycle.
|
||||||
|
//
|
||||||
//go:linkname save hakurei.app/internal/store.(*EntryHandle).save
|
//go:linkname save hakurei.app/internal/store.(*EntryHandle).save
|
||||||
func save(eh *store.EntryHandle, state *hst.State) error
|
func save(eh *store.EntryHandle, state *hst.State) error
|
||||||
|
|
||||||
@ -91,9 +96,9 @@ func TestStateEntryHandle(t *testing.T) {
|
|||||||
t.Run("saveload", func(t *testing.T) {
|
t.Run("saveload", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
eh := store.EntryHandle{Pathname: check.MustAbs(t.TempDir()).Append("entry"),
|
eh := store.EntryHandle{Pathname: check.MustAbs(t.TempDir()).Append("entry"),
|
||||||
ID: newTemplateState().ID}
|
ID: store.NewTemplateState().ID}
|
||||||
|
|
||||||
if err := save(&eh, newTemplateState()); err != nil {
|
if err := save(&eh, store.NewTemplateState()); err != nil {
|
||||||
t.Fatalf("save: error = %v", err)
|
t.Fatalf("save: error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +117,7 @@ func TestStateEntryHandle(t *testing.T) {
|
|||||||
t.Fatal(f.Close())
|
t.Fatal(f.Close())
|
||||||
}
|
}
|
||||||
|
|
||||||
if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
|
if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
|
||||||
t.Errorf("entryDecode: %#v, want %#v", &got, want)
|
t.Errorf("entryDecode: %#v, want %#v", &got, want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -122,7 +127,7 @@ func TestStateEntryHandle(t *testing.T) {
|
|||||||
|
|
||||||
if et, err := eh.Load(nil); err != nil {
|
if et, err := eh.Load(nil); err != nil {
|
||||||
t.Fatalf("load: error = %v", err)
|
t.Fatalf("load: error = %v", err)
|
||||||
} else if want := newTemplateState().Enablements.Unwrap(); et != want {
|
} else if want := store.NewTemplateState().Enablements.Unwrap(); et != want {
|
||||||
t.Errorf("load: et = %x, want %x", et, want)
|
t.Errorf("load: et = %x, want %x", et, want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -133,7 +138,7 @@ func TestStateEntryHandle(t *testing.T) {
|
|||||||
var got hst.State
|
var got hst.State
|
||||||
if _, err := eh.Load(&got); err != nil {
|
if _, err := eh.Load(&got); err != nil {
|
||||||
t.Fatalf("load: error = %v", err)
|
t.Fatalf("load: error = %v", err)
|
||||||
} else if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
|
} else if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
|
||||||
t.Errorf("load: %#v, want %#v", &got, want)
|
t.Errorf("load: %#v, want %#v", &got, want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -12,13 +12,15 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
_ "unsafe"
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"hakurei.app/container/check"
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal/store"
|
"hakurei.app/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Made available here to check bigLock error handling behaviour.
|
||||||
|
//
|
||||||
//go:linkname bigLock hakurei.app/internal/store.(*Store).bigLock
|
//go:linkname bigLock hakurei.app/internal/store.(*Store).bigLock
|
||||||
func bigLock(s *store.Store) (unlock func(), err error)
|
func bigLock(s *store.Store) (unlock func(), err error)
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user