diff --git a/.gitmodules b/.gitmodules index 5c6ecb4..a145d1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "git"] url = https://git.kernel.org/pub/scm/git/git.git path = git + +[submodule "qssb"] + path = qssb + url = https://git.quitesimple.org/qssb.h/ diff --git a/cgit.c b/cgit.c index ac8c641..eb33b98 100644 --- a/cgit.c +++ b/cgit.c @@ -16,7 +16,7 @@ #include "ui-blob.h" #include "ui-summary.h" #include "scan-tree.h" - +#include "qssb/qssb.h" const char *cgit_version = CGIT_VERSION; __attribute__((constructor)) @@ -1046,6 +1046,30 @@ static int calc_ttl(void) return ctx.cfg.cache_repo_ttl; } +void enable_sandbox() +{ + struct qssb_policy *policy = qssb_init_policy(); + + size_t allowed_paths_length = cgit_repolist.count+2; + char **allowed_paths = malloc(sizeof(char *) * allowed_paths_length); + allowed_paths[0] = "/dev/"; //TODO: drop this once qssb can create some minimal /dev itself + for(int i = 0; i < cgit_repolist.count; i++) + { + struct cgit_repo *current = &cgit_repolist.repos[i]; + allowed_paths[i+1] = current->path; + } + allowed_paths[allowed_paths_length-1] = NULL; + policy->readonly_paths = allowed_paths; + if(qssb_enable_policy(policy) != 0) + { + fprintf(stderr, "%s", "Failed to init sandbox\n"); + exit(EXIT_FAILURE); + } + + free(allowed_paths); + qssb_free_policy(policy); +} + int cmd_main(int argc, const char **argv) { const char *path; @@ -1064,6 +1088,8 @@ int cmd_main(int argc, const char **argv) ctx.repo = NULL; http_parse_querystring(ctx.qry.raw, querystring_cb); + enable_sandbox(); + /* If virtual-root isn't specified in cgitrc, lets pretend * that virtual-root equals SCRIPT_NAME, minus any possibly * trailing slashes. diff --git a/qssb b/qssb new file mode 160000 index 0000000..1635ffc --- /dev/null +++ b/qssb @@ -0,0 +1 @@ +Subproject commit 1635ffce087130ca25f97a31841c9d28f7808b87