diff --git a/doc/pacman.8.asciidoc b/doc/pacman.8.asciidoc index e0c3b73d..f2ac1ea1 100644 --- a/doc/pacman.8.asciidoc +++ b/doc/pacman.8.asciidoc @@ -205,6 +205,18 @@ Options systems. Useful if experiencing landlock related failures while downloading files when running a Linux kernel that does not support this feature. +*\--disable-fs-sandbox*:: + Disable the filesystem part of the sandbox applied to the process downloading + files on Linux systems. Useful if experiencing Landlock related failures + while downloading files when running a Linux kernel that does not support + this feature. + +*\--disable-syscalls-sandbox*:: + Disable the syscalls part of the sandbox applied to the process downloading + files on Linux systems. Useful if experiencing seccomp related failures + while downloading files when running a Linux kernel that does not support + this feature. + Transaction Options (apply to '-S', '-R' and '-U') -------------------------------------------------- *-d, \--nodeps*:: diff --git a/doc/pacman.conf.5.asciidoc b/doc/pacman.conf.5.asciidoc index 16dc7950..e8dbe9b4 100644 --- a/doc/pacman.conf.5.asciidoc +++ b/doc/pacman.conf.5.asciidoc @@ -216,6 +216,18 @@ Options systems. Useful if experiencing landlock related failures while downloading files when running a Linux kernel that does not support this feature. +*DisableFilesystemSandbox*:: + Disable the filesystem part of the sandbox applied to the process downloading + files on Linux systems. Useful if experiencing Landlock related failures + while downloading files when running a Linux kernel that does not support + this feature. + +*DisableSyscallsSandbox*:: + Disable the syscalls part of the sandbox applied to the process downloading + files on Linux systems. Useful if experiencing seccomp related failures + while downloading files when running a Linux kernel that does not support + this feature. + Repository Sections ------------------- Each repository section defines a section name and at least one location where diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in index 50e5a1da..47d93de0 100644 --- a/etc/pacman.conf.in +++ b/etc/pacman.conf.in @@ -37,6 +37,8 @@ CheckSpace ParallelDownloads = 5 #DownloadUser = alpm #DisableSandbox +#DisableFilesystemSandbox +#DisableSyscallsSandbox # PGP signature checking #SigLevel = Optional diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 96e5e643..26a77e01 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -2317,6 +2317,32 @@ int alpm_option_get_disable_sandbox(alpm_handle_t *handle); * @return 0 on success, -1 on error (pm_errno is set accordingly) */ int alpm_option_set_disable_sandbox(alpm_handle_t *handle, unsigned short disable_sandbox); + +/** Get the state of the filesystem part of the sandbox + * @param handle the context handle + * @return 0 for enabled, 1 for disabled + */ +int alpm_option_get_disable_filesystem_sandbox(alpm_handle_t *handle); + +/** Enables/disables the filesystem part of the sandbox. + * @param handle the context handle + * @param disable_fs_sandbox 0 for enabled, 1 for disabled + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int alpm_option_set_disable_filesystem_sandbox(alpm_handle_t *handle, unsigned short disable_fs_sandbox); + +/** Get the state of the syscalls part of the sandbox + * @param handle the context handle + * @return 0 for enabled, 1 for disabled + */ +int alpm_option_get_disable_syscalls_sandbox(alpm_handle_t *handle); + +/** Enables/disables the syscalls part of the sandbox. + * @param handle the context handle + * @param disable_syscalls_sandbox 0 for enabled, 1 for disabled + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int alpm_option_set_disable_syscalls_sandbox(alpm_handle_t *handle, unsigned short disable_syscalls_sandbox); /* End of disable_sandbox accessors */ /** @} */ diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 6633f2f5..5f9779f3 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -971,3 +971,31 @@ int SYMEXPORT alpm_option_set_disable_sandbox(alpm_handle_t *handle, handle->disable_sandbox = disable_sandbox; return 0; } + +int SYMEXPORT alpm_option_get_disable_filesystem_sandbox(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return -1); + return handle->disable_fs_sandbox; +} + +int SYMEXPORT alpm_option_set_disable_filesystem_sandbox(alpm_handle_t *handle, + unsigned short disable_fs_sandbox) +{ + CHECK_HANDLE(handle, return -1); + handle->disable_fs_sandbox = disable_fs_sandbox; + return 0; +} + +int SYMEXPORT alpm_option_get_disable_syscalls_sandbox(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return -1); + return handle->disable_syscalls_sandbox; +} + +int SYMEXPORT alpm_option_set_disable_syscalls_sandbox(alpm_handle_t *handle, + unsigned short disable_syscalls_sandbox) +{ + CHECK_HANDLE(handle, return -1); + handle->disable_syscalls_sandbox = disable_syscalls_sandbox; + return 0; +} diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2637a92f..fe1bc411 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -65,7 +65,9 @@ struct _alpm_handle_t { #endif unsigned short disable_dl_timeout; + unsigned short disable_fs_sandbox; unsigned short disable_sandbox; + unsigned short disable_syscalls_sandbox; unsigned int parallel_downloads; /* number of download streams */ #ifdef HAVE_LIBGPGME diff --git a/lib/libalpm/sandbox.c b/lib/libalpm/sandbox.c index f725aed6..b8346f0e 100644 --- a/lib/libalpm/sandbox.c +++ b/lib/libalpm/sandbox.c @@ -42,14 +42,14 @@ int SYMEXPORT alpm_sandbox_setup_child(alpm_handle_t *handle, const char* sandbo ASSERT(sandboxuser != NULL, return -1); ASSERT(getuid() == 0, return -1); ASSERT((pw = getpwnam(sandboxuser)), return -1); - if(sandbox_path != NULL && !handle->disable_sandbox) { + if(sandbox_path != NULL && !handle->disable_sandbox && !handle->disable_fs_sandbox) { ASSERT(_alpm_sandbox_fs_restrict_writes_to(handle, sandbox_path), return -1); } #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NO_NEW_PRIVS) /* make sure that we cannot gain more privileges later, failure is fine */ prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); #endif /* HAVE_SYS_PRCTL && PR_SET_NO_NEW_PRIVS */ - if(restrict_syscalls && !handle->disable_sandbox) { + if(restrict_syscalls && !handle->disable_sandbox && !handle->disable_syscalls_sandbox) { ASSERT(_alpm_sandbox_syscalls_filter(handle), return -1); } ASSERT(setgid(pw->pw_gid) == 0, return -1); diff --git a/src/pacman/conf.c b/src/pacman/conf.c index a0e0e96a..932c1ce7 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -629,8 +629,12 @@ static int _parse_options(const char *key, char *value, config->noprogressbar = 1; } else if(strcmp(key, "DisableDownloadTimeout") == 0) { config->disable_dl_timeout = 1; + } else if(strcmp(key, "DisableFilesystemSandbox") == 0) { + config->disable_fs_sandbox = 1; } else if(strcmp(key, "DisableSandbox") == 0) { config->disable_sandbox = 1; + } else if(strcmp(key, "DisableSyscallsSandbox") == 0) { + config->disable_syscalls_sandbox = 1; } else { pm_printf(ALPM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), @@ -944,6 +948,8 @@ static int setup_libalpm(void) } alpm_option_set_disable_sandbox(handle, config->disable_sandbox); + alpm_option_set_disable_filesystem_sandbox(handle, config->disable_fs_sandbox); + alpm_option_set_disable_syscalls_sandbox(handle, config->disable_syscalls_sandbox); alpm_option_set_ignorepkgs(handle, config->ignorepkg); alpm_option_set_ignoregroups(handle, config->ignoregrp); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 2c4fddf0..14230e66 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -58,7 +58,9 @@ typedef struct __config_t { unsigned short usesyslog; unsigned short color; unsigned short disable_dl_timeout; + unsigned short disable_fs_sandbox; unsigned short disable_sandbox; + unsigned short disable_syscalls_sandbox; char *print_format; /* unfortunately, we have to keep track of paths both here and in the library * because they can come from both the command line or config file, and we @@ -214,7 +216,9 @@ enum { OP_REFRESH, OP_ASSUMEINSTALLED, OP_DISABLEDLTIMEOUT, - OP_DISABLESANDBOX + OP_DISABLEFSSANDBOX, + OP_DISABLESANDBOX, + OP_DISABLESYSCALLSSANDBOX }; /* clean method */ diff --git a/src/pacman/pacman-conf.c b/src/pacman/pacman-conf.c index 8a0dfed8..d33ae1f6 100644 --- a/src/pacman/pacman-conf.c +++ b/src/pacman/pacman-conf.c @@ -280,7 +280,9 @@ static void dump_config(void) show_bool("DisableDownloadTimeout", config->disable_dl_timeout); show_bool("ILoveCandy", config->chomp); show_bool("NoProgressBar", config->noprogressbar); + show_bool("DisableFilesystemSandbox", config->disable_fs_sandbox); show_bool("DisableSandbox", config->disable_sandbox); + show_bool("DisableSyscallsSandbox", config->disable_syscalls_sandbox); show_int("ParallelDownloads", config->parallel_downloads); @@ -398,8 +400,12 @@ static int list_directives(void) show_bool("ILoveCandy", config->chomp); } else if(strcasecmp(i->data, "NoProgressBar") == 0) { show_bool("NoProgressBar", config->noprogressbar); + } else if(strcasecmp(i->data, "DisableFilesystemSandbox") == 0) { + show_bool("DisableFilesystemSandbox", config->disable_fs_sandbox); } else if(strcasecmp(i->data, "DisableSandbox") == 0) { show_bool("DisableSandbox", config->disable_sandbox); + } else if(strcasecmp(i->data, "DisableSyscallsSandbox") == 0) { + show_bool("DisableSyscallsSandbox", config->disable_syscalls_sandbox); } else if(strcasecmp(i->data, "ParallelDownloads") == 0) { show_int("ParallelDownloads", config->parallel_downloads); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 2866fc98..8ca300d8 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -228,6 +228,10 @@ static void usage(int op, const char * const myname) " use relaxed timeouts for download\n")); addlist(_(" --disable-sandbox\n" " disable the sandbox used for the downloader process\n")); + addlist(_(" --disable-fs-sandbox\n" + " disable the filesystem part of the sandbox used for the downloader process\n")); + addlist(_(" --disable-syscalls-sandbox\n" + " disable the syscalls part of the sandbox used for the downloader process\n")); } list = alpm_list_msort(list, alpm_list_count(list), options_cmp); for(i = list; i; i = alpm_list_next(i)) { @@ -492,9 +496,15 @@ static int parsearg_global(int opt) case OP_DISABLEDLTIMEOUT: config->disable_dl_timeout = 1; break; + case OP_DISABLEFSSANDBOX: + config->disable_fs_sandbox = 1; + break; case OP_DISABLESANDBOX: config->disable_sandbox = 1; break; + case OP_DISABLESYSCALLSSANDBOX: + config->disable_syscalls_sandbox = 1; + break; case OP_VERBOSE: case 'v': (config->verbose)++; @@ -981,7 +991,9 @@ static int parseargs(int argc, char *argv[]) {"dbonly", no_argument, 0, OP_DBONLY}, {"color", required_argument, 0, OP_COLOR}, {"disable-download-timeout", no_argument, 0, OP_DISABLEDLTIMEOUT}, + {"disable-fs-sandbox", no_argument, 0, OP_DISABLEFSSANDBOX}, {"disable-sandbox", no_argument, 0, OP_DISABLESANDBOX}, + {"disable-syscalls-sandbox", no_argument, 0, OP_DISABLESYSCALLSSANDBOX}, {0, 0, 0, 0} };