diff --git a/ffi/build.rs b/ffi/build.rs index 4b40455..08f1120 100644 --- a/ffi/build.rs +++ b/ffi/build.rs @@ -27,4 +27,7 @@ fn main() { let target_dir = PathBuf::from(&crate_dir).join("c"); fs::copy(&header_path, target_dir.join(header_file)).expect("Failed to copy header file"); + + let target_dir = PathBuf::from(&crate_dir).join("go"); + fs::copy(&header_path, target_dir.join(header_file)).expect("Failed to copy header file"); } diff --git a/ffi/go b/ffi/go new file mode 120000 index 0000000..28f368e --- /dev/null +++ b/ffi/go @@ -0,0 +1 @@ +../go \ No newline at end of file diff --git a/go/Makefile b/go/Makefile new file mode 100644 index 0000000..0157365 --- /dev/null +++ b/go/Makefile @@ -0,0 +1,11 @@ +LIB_PATH=../target/debug +TARGET = sandboxer + +all: $(TARGET) + +run: $(TARGET) + LD_LIBRARY_PATH=$(LIB_PATH) ./$(TARGET) + +$(TARGET): + cargo build + go build ./cmd/... diff --git a/go/cmd/sandboxer/sandboxer.go b/go/cmd/sandboxer/sandboxer.go new file mode 100644 index 0000000..5dd43ba --- /dev/null +++ b/go/cmd/sandboxer/sandboxer.go @@ -0,0 +1,36 @@ +package main + +import ( + "log" + "os" + "syscall" + + ll "github.com/landlock-lsm/go-landlock/landlock/syscall" + "github.com/landlock-lsm/landlockconfig" + "golang.org/x/sys/unix" +) + +func main() { + // f, err := os.Open("config.toml") + // if err != nil { + // log.Fatalf("failed reading file") + // } + + b, err := os.ReadFile("config.toml") + if err != nil { + log.Fatalf("failed reading file") + } + // s := LandlockConfigParseToml(f) + s := landlockconfig.LandlockconfigParseTomlBuffer(b) + n := landlockconfig.LandlockConfigBuildRulseset(s) + if err := ll.AllThreadsPrctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { + log.Fatal(err) + } + if err := ll.AllThreadsLandlockRestrictSelf(n, 0); err != nil { + log.Fatal(err) + } + err = syscall.Exec("/bin/bash", []string{"-i"}, os.Environ()) + if err != nil { + log.Fatalf("could not execve ct, error: %v", err) + } +} diff --git a/go/config.toml b/go/config.toml new file mode 120000 index 0000000..0e28847 --- /dev/null +++ b/go/config.toml @@ -0,0 +1 @@ +../examples/mini-write-tmp.toml \ No newline at end of file diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 0000000..9e95e4b --- /dev/null +++ b/go/go.mod @@ -0,0 +1,10 @@ +module github.com/landlock-lsm/landlockconfig + +go 1.24.3 + +require ( + github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 + golang.org/x/sys v0.33.0 +) + +require kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect diff --git a/go/go.sum b/go/go.sum new file mode 100644 index 0000000..35a0dee --- /dev/null +++ b/go/go.sum @@ -0,0 +1,6 @@ +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 h1:zcMi8R8vP0WrrXlFMNUBpDy/ydo3sTnCcUPowq1XmSc= +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3/go.mod h1:RSub3ourNF8Hf+swvw49Catm3s7HVf4hzdFxDUnEzdA= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= diff --git a/go/landlockconfig.go b/go/landlockconfig.go new file mode 100644 index 0000000..8170eba --- /dev/null +++ b/go/landlockconfig.go @@ -0,0 +1,43 @@ +package landlockconfig + +// #cgo CFLAGS: -Wall -Werror -g -I../include +// #cgo LDFLAGS: -L../target/release -llandlockconfig +// #include "landlockconfig.h" +import "C" + +import ( + "os" + "unsafe" +) + +type LandlockConfig struct { + s *C.struct_landlockconfig +} + +func LandlockConfigParseJson(f *os.File) *LandlockConfig { + return &LandlockConfig{ + C.landlockconfig_parse_json_file(C.int(f.Fd()), 0), + } +} + +func LandlockConfigParseToml(f *os.File) *LandlockConfig { + return &LandlockConfig{ + C.landlockconfig_parse_toml_file(C.int(f.Fd()), 0), + } +} + +func LandlockConfigParseFree(s *LandlockConfig) { + C.landlockconfig_free(s.s) +} + +func LandlockConfigBuildRulseset(s *LandlockConfig) int { + return int(C.landlockconfig_build_ruleset(s.s, 0)) +} + +func LandlockconfigParseTomlBuffer(b []byte) *LandlockConfig { + return &LandlockConfig{C.landlockconfig_parse_toml_buffer((*C.uint8_t)(unsafe.Pointer(&b[0])), C.uintptr_t(len(b)), 0)} +} + +func LandlockconfigParseJsonBuffer(b []byte) *LandlockConfig { + return &LandlockConfig{C.landlockconfig_parse_json_buffer((*C.uint8_t)(unsafe.Pointer(&b[0])), C.uintptr_t(len(b)), 0)} +} diff --git a/go/landlockconfig.h b/go/landlockconfig.h new file mode 100644 index 0000000..32942ac --- /dev/null +++ b/go/landlockconfig.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* Auto-generated by cbindgen. */ + +#ifndef LANDLOCKCONFIG_H +#define LANDLOCKCONFIG_H + +#include + +struct landlockconfig; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Parses a JSON configuration file + * + * # Parameters + * + * * `config_fd`: A file descriptor referring to a JSON configuration file. + * * `flags`: Must be 0. + * + * # Return values + * + * * Pointer to a landlockconfig object on success. This object must be freed + * with landlockconfig_free(). + * * -errno on error. + */ +struct landlockconfig *landlockconfig_parse_json_file(int config_fd, uint32_t flags); + +/** + * Parses a TOML configuration file + * + * # Parameters + * + * * `config_fd`: A file descriptor referring to a TOML configuration file. + * * `flags`: Must be 0. + * + * # Return values + * + * * Pointer to a landlockconfig object on success. This object must be freed + * with landlockconfig_free(). + * * -errno on error. + */ +struct landlockconfig *landlockconfig_parse_toml_file(int config_fd, uint32_t flags); + +/** + * Parses a JSON configuration from a memory buffer + * + * # Parameters + * + * * `buffer_ptr`: Pointer to the buffer containing JSON data. + * * `buffer_size`: Size of the buffer in bytes, or 0 if `buffer_ptr` is null-terminated. + * * `flags`: Must be 0. + * + * # Return values + * + * * Pointer to a landlockconfig object on success. This object must be freed + * with landlockconfig_free(). + * * -errno on error. + */ +struct landlockconfig *landlockconfig_parse_json_buffer(const uint8_t *buffer_ptr, + uintptr_t buffer_size, + uint32_t flags); + +/** + * Parses a TOML configuration from a memory buffer + * + * # Parameters + * + * * `buffer_ptr`: Pointer to the buffer containing TOML data. + * * `buffer_size`: Size of the buffer in bytes, or 0 if `buffer_ptr` is null-terminated. + * * `flags`: Must be 0. + * + * # Return values + * + * * Pointer to a landlockconfig object on success. This object must be freed + * with landlockconfig_free(). + * * -errno on error. + */ +struct landlockconfig *landlockconfig_parse_toml_buffer(const uint8_t *buffer_ptr, + uintptr_t buffer_size, + uint32_t flags); + +/** + * Frees a landlockconfig object + * + * # Safety + * + * The pointer must have been returned by landlockconfig_parse_json() or + * landlockconfig_parse_toml(). + */ +void landlockconfig_free(struct landlockconfig *config); + +/** + * Creates a ruleset from a landlockconfig object + * + * # Parameters + * + * * `config`: A pointer to a landlockconfig object. + * * `flags`: Must be 0. + * + * # Safety + * + * `config` must have been returned by landlockconfig_parse_json() or + * landlockconfig_parse_toml(). + * + * # Returns + * + * * The ruleset file descriptor on success. + * * -errno on error. + */ +int landlockconfig_build_ruleset(const struct landlockconfig *config, uint32_t flags); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* LANDLOCKCONFIG_H */