@@ -22,7 +22,7 @@ ifeq ($(ARCH), mac) | |||||
CXXFLAGS += -DAPPLE -stdlib=libc++ | CXXFLAGS += -DAPPLE -stdlib=libc++ | ||||
LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | ||||
-framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | -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 | TARGET = Rack | ||||
BUNDLE = dist/$(TARGET).app | BUNDLE = dist/$(TARGET).app | ||||
endif | endif | ||||
@@ -56,11 +56,6 @@ ifeq ($(ARCH), win) | |||||
env PATH=dep/bin:/mingw64/bin ./$< | env PATH=dep/bin:/mingw64/bin ./$< | ||||
endif | endif | ||||
sandbox-run: $(TARGET) | |||||
ifeq ($(ARCH), mac) | |||||
sandbox-exec -D RACK_HOME=$(PWD) -f ./Rack.sb `which sh` -c 'DYLD_FALLBACK_LIBRARY_PATH=dep/lib ./$<' 2 ↵ ✹ ✭sandbox ‹2.4.2› | |||||
endif | |||||
debug: $(TARGET) | debug: $(TARGET) | ||||
ifeq ($(ARCH), lin) | ifeq ($(ARCH), lin) | ||||
LD_LIBRARY_PATH=dep/lib gdb -ex run ./Rack | LD_LIBRARY_PATH=dep/lib gdb -ex run ./Rack | ||||
@@ -97,6 +92,7 @@ ifeq ($(ARCH), mac) | |||||
mkdir -p $(BUNDLE)/Contents/Resources | mkdir -p $(BUNDLE)/Contents/Resources | ||||
cp Info.plist $(BUNDLE)/Contents/ | cp Info.plist $(BUNDLE)/Contents/ | ||||
cp -R LICENSE* res $(BUNDLE)/Contents/Resources | cp -R LICENSE* res $(BUNDLE)/Contents/Resources | ||||
cp Rack.sb $(BUNDLE)/Contents/Resources | |||||
mkdir -p $(BUNDLE)/Contents/MacOS | mkdir -p $(BUNDLE)/Contents/MacOS | ||||
cp Rack $(BUNDLE)/Contents/MacOS/ | cp Rack $(BUNDLE)/Contents/MacOS/ | ||||
@@ -1,26 +1,15 @@ | |||||
(version 1) | (version 1) | ||||
(debug allow) | |||||
(define rack-home "RACK_HOME") | |||||
(import "system.sb") | |||||
; This is needed for IPC on OSX >= 10.6 | |||||
(allow ipc-posix-shm) | (allow ipc-posix-shm) | ||||
; Allow inbound and outbound connections | |||||
(allow network-outbound) | (allow network-outbound) | ||||
(allow network-inbound) | (allow network-inbound) | ||||
; Allow reading with sysctl | |||||
(allow sysctl-read) | (allow sysctl-read) | ||||
; Allow it to read metadata | |||||
(allow file-read-metadata) | (allow file-read-metadata) | ||||
; Allow it to run processes and fork | |||||
(allow process*) | |||||
; Allow it to signal self | |||||
(allow signal) | (allow signal) | ||||
(allow iokit-open) | (allow iokit-open) | ||||
@@ -29,34 +18,8 @@ | |||||
(allow system-socket) | (allow system-socket) | ||||
(allow file-read* file-write* (subpath (param rack-home))) | |||||
; Allow file reading | |||||
(allow file-read* | |||||
(regex | |||||
#"^/Applications/Rack.app" | |||||
#"^/Library/*" | |||||
#"^/System/Library/*" | |||||
#"^/usr/*" | |||||
#"^/dev/*" | |||||
#"/Users/jon/Projects/Rack" | |||||
#"/Users/[^.]+/Library/Saved Application State/com.vcvrack.rack.savedState" | |||||
) | |||||
) | |||||
; Allow write access to a subset of the above | |||||
(allow file-write* | |||||
(regex | |||||
#"^/private/var/*" | |||||
#"^/private/tmp/*" | |||||
#"^/var/folders/th/*" | |||||
) | |||||
) | |||||
(allow file-issue-extension | |||||
(regex | |||||
#"^/private/var/*" | |||||
) | |||||
) | |||||
(allow file-read* (subpath (param "rackLocal"))) | |||||
(allow file-write* (subpath (param "rackLocal"))) | |||||
(allow file-read* (subpath (param "rackGlobal"))) | |||||
(deny default) | (deny default) |
@@ -32,7 +32,10 @@ int main(int argc, char* argv[]) { | |||||
info("Local directory: %s", localDir.c_str()); | info("Local directory: %s", localDir.c_str()); | ||||
} | } | ||||
sandboxInit(); | |||||
if(!sandboxInit()) { | |||||
info("Refusing to run without sandbox"); | |||||
exit(1); | |||||
} | |||||
pluginInit(); | pluginInit(); | ||||
engineInit(); | engineInit(); | ||||
guiInit(); | guiInit(); | ||||
@@ -1,13 +1,71 @@ | |||||
#include "sandbox.hpp" | #include "sandbox.hpp" | ||||
#include "util.hpp" | #include "util.hpp" | ||||
#include "asset.hpp" | |||||
#include <vector> | |||||
namespace rack { | namespace rack { | ||||
#if defined(ARCH_MAC) | #if defined(ARCH_MAC) | ||||
#include <sandbox.h> | #include <sandbox.h> | ||||
#include <stdlib.h> | |||||
#include <sys/syslimits.h> | |||||
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() { | bool sandboxInit() { | ||||
char* error_buff = NULL; | |||||
//int error = sandbox_init(final_sandbox_profile_str.c_str(), 0, &error_buff); | |||||
int error = sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, &error_buff); | |||||
/* | |||||
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<const char *> 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); | bool success = (error == 0 && error_buff == NULL); | ||||
if(!success) { | if(!success) { | ||||
info("Sandbox initialization error (%d): %s", error, error_buff); | info("Sandbox initialization error (%d): %s", error, error_buff); | ||||
@@ -16,6 +74,11 @@ bool sandboxInit() { | |||||
} | } | ||||
sandbox_free_error(error_buff); | sandbox_free_error(error_buff); | ||||
FILE *file2 = fopen("/Users/jon/Documents/mg.txt", "rb"); | |||||
if(!file2) { | |||||
info("Couldn't read private file"); | |||||
} | |||||
return success; | return success; | ||||
} | } | ||||