diff --git a/Makefile b/Makefile index 792cdbb5..17ddb649 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ FLAGS += \ SOURCES = $(wildcard src/*.cpp src/*/*.cpp) \ ext/nanovg/src/nanovg.c - include arch.mk ifeq ($(ARCH), lin) @@ -23,7 +22,7 @@ ifeq ($(ARCH), mac) CXXFLAGS += -DAPPLE -stdlib=libc++ LDFLAGS += -stdlib=libc++ -lpthread -ldl \ -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ - -Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi -lcrypto + -Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lsandbox TARGET = Rack BUNDLE = dist/$(TARGET).app endif @@ -93,6 +92,7 @@ ifeq ($(ARCH), mac) mkdir -p $(BUNDLE)/Contents/Resources cp Info.plist $(BUNDLE)/Contents/ cp -R LICENSE* res $(BUNDLE)/Contents/Resources + cp Rack.sb $(BUNDLE)/Contents/Resources mkdir -p $(BUNDLE)/Contents/MacOS cp Rack $(BUNDLE)/Contents/MacOS/ diff --git a/Rack.sb b/Rack.sb new file mode 100644 index 00000000..8feb9e92 --- /dev/null +++ b/Rack.sb @@ -0,0 +1,25 @@ +(version 1) +(import "system.sb") + +(allow ipc-posix-shm) + +(allow network-outbound) +(allow network-inbound) + +(allow sysctl-read) + +(allow file-read-metadata) + +(allow signal) + +(allow iokit-open) + +(allow mach-lookup) + +(allow system-socket) + +(allow file-read* (subpath (param "rackLocal"))) +(allow file-write* (subpath (param "rackLocal"))) +(allow file-read* (subpath (param "rackGlobal"))) + +(deny default) diff --git a/include/sandbox.hpp b/include/sandbox.hpp new file mode 100644 index 00000000..3d59a4f5 --- /dev/null +++ b/include/sandbox.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace rack { +bool sandboxInit(); +} diff --git a/src/main.cpp b/src/main.cpp index bc32af17..7aa30331 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include "engine.hpp" #include "gui.hpp" #include "app.hpp" +#include "sandbox.hpp" #include "plugin.hpp" #include "settings.hpp" #include "asset.hpp" @@ -31,6 +32,10 @@ int main(int argc, char* argv[]) { info("Local directory: %s", localDir.c_str()); } + if(!sandboxInit()) { + info("Refusing to run without sandbox"); + exit(1); + } pluginInit(); engineInit(); guiInit(); diff --git a/src/sandbox.cpp b/src/sandbox.cpp new file mode 100644 index 00000000..3d4840d1 --- /dev/null +++ b/src/sandbox.cpp @@ -0,0 +1,85 @@ +#include "sandbox.hpp" +#include "util.hpp" +#include "asset.hpp" +#include + +namespace rack { +#if defined(ARCH_MAC) +#include +#include +#include +extern "C" { + +int sandbox_init_with_parameters(const char *profile, uint64_t flags, const char *const parameters[], char **errorbuf); +// Possible values for 'flags': +#define SANDBOX_STRING 0x0000 +#define SANDBOX_NAMED 0x0001 +#define SANDBOX_BUILTIN 0x0002 +#define SANDBOX_FILE 0x0003 + +} + +struct SandboxParams { + void* buf; + size_t count; + size_t size; +}; + +bool sandboxInit() { + + /* + char* params = sandbox_create_params(); + if (!params) + return false; + + sandbox_set_param(params, "rackGlobal", assetGlobal("").c_str()); + sandbox_set_param(params, "rackLocal", assetLocal("").c_str()); + */ + std::string profilePath = assetGlobal("Rack.sb").c_str(); + FILE *file = fopen(profilePath.c_str(), "rb"); + if(!file) { + info("Couldn't read sandbox profile"); + return false; + } + fseek(file, 0, SEEK_END); + long fsize = ftell(file); + fseek(file, 0, SEEK_SET); //same as rewind(f); + + char *profileStr = (char*)malloc(fsize + 1); + fread(profileStr, fsize, 1, file); + fclose(file); + profileStr[fsize] = 0; + + std::vector params; + char resolved_path[PATH_MAX]; + + params.push_back("rackGlobal"); + realpath(assetGlobal("").c_str(), resolved_path); + params.push_back(resolved_path); + + params.push_back("rackLocal"); + realpath(assetLocal("").c_str(), resolved_path); + params.push_back(resolved_path); + + // The parameters array is null terminated. + params.push_back(nullptr); + + char* error_buff = nullptr; + int error = sandbox_init_with_parameters(profileStr, SANDBOX_STRING, params.data(), &error_buff); + bool success = (error == 0 && error_buff == NULL); + if(!success) { + info("Sandbox initialization error (%d): %s", error, error_buff); + } else { + info("Sandbox initialized!"); + } + sandbox_free_error(error_buff); + return success; +} + + +#else + bool sandboxInit() { + return false; + } +#endif +}