diff --git a/.editorconfig b/.editorconfig index 220ffbc8..d7ee9c26 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ # EditorConfig configuration for pacman -# http://EditorConfig.org +# https://editorconfig.org # Top-most EditorConfig file root = true diff --git a/NEWS b/NEWS index 5d7c07cd..b67fe49b 100644 --- a/NEWS +++ b/NEWS @@ -15,7 +15,7 @@ VERSION DESCRIPTION - makepkg: - Replace libdepends and libprovides with autodeps - Support configuration via makepkg.conf.d drop-ins - - Add GITFLAGS environmental variable to customize checkouts + - Add GITFLAGS environment variable to customize checkouts - Add -D option to change directory before building - Implement verify() function for custom source verificaton - Add checksum support for git/mercurial/bzr sources @@ -182,7 +182,7 @@ VERSION DESCRIPTION - fix segfault when Usage is specified without a value - include timezones in pacman.log - bash-completion: use POSIX character classes for portability - - correctly report a download failiure for 404s + - correctly report a download failure for 404s - fix handling of signals during SIGSEGV - fix buffer overread in pacman/callback - fix crash when downloading files with a Content-Disposition @@ -585,8 +585,8 @@ VERSION DESCRIPTION - remove --asroot and enforce fakeroot usage - all PKGBUILDs require a package() function - PKGBUILDs can no longer be read from stdin - - enable make style environmental overrides - - Read CARCH environmental variable (FS#35030) + - enable make-style environment variable overrides + - Read CARCH environment variable (FS#35030) - makedepends and checkdepends are installed together (FS#31557) - added support for sha224 checksums (FS#36776) - remove warning when license is not specified in PKGBUILD @@ -683,7 +683,7 @@ VERSION DESCRIPTION - pkgrel must be in decimal format - PKGBUILDs without package() functions are deprecated - support specifying CPPFLAGS in makepkg.conf - - support PACKAGER environmental variable + - support PACKAGER environment variable - allow source renaming to work on signature files - configurable compression options (FS#27430) - allow multiple packages to be build when using @@ -697,7 +697,7 @@ VERSION DESCRIPTION - add LOGDEST configuration option - install makedepends with --repackage - repo-add: - - honor TMPDIR environmental variable + - honor TMPDIR environment variable - add makedepends/checkdepends information to database - pacman-key: - fix importing keys with quotes in file name (FS#28445) diff --git a/doc/makepkg.8.asciidoc b/doc/makepkg.8.asciidoc index 5ba13ace..bb5e2f4a 100644 --- a/doc/makepkg.8.asciidoc +++ b/doc/makepkg.8.asciidoc @@ -144,7 +144,8 @@ Options Display version information. *-C, \--cleanbuild*:: - Remove the $srcdir before building the package. + Clean build artifacts from previous runs of makepkg in the current + directory by removing $srcdir before building the package. *-D* , *\--dir* :: Change to directory before reading the PKGBUILD or doing anything else. @@ -296,9 +297,11 @@ Environment Variables **BUILDTOOLVER=**"":: The version of the '$BUILDTOOL' used. -**GITFLAGS**:: - The options to pass when checking out git sources, replacing the default - "--mirror". +**MAKEPKG_LINT_PKGBUILD=**0 + Setting to 0 disables PKGBUILD linting within makepkg. Useful on systems + with slow bash subshell operations, or on PKGBUILDs with extreme amounts of + package splitting. + Configuration ------------- diff --git a/doc/makepkg.conf.5.asciidoc b/doc/makepkg.conf.5.asciidoc index 57fbc966..36dcb77e 100644 --- a/doc/makepkg.conf.5.asciidoc +++ b/doc/makepkg.conf.5.asciidoc @@ -23,6 +23,9 @@ NOTE: This does not guarantee that all package Makefiles will use your exported variables. Some of them are non-standard. The system-wide configuration file is found in {sysconfdir}/makepkg.conf. +Specific additions (e.g. build flags for additional languages) can be placed +in {sysconfdir}/makepkg.conf.d/*.conf. + Individual options can be overridden (or added to) on a per-user basis in $XDG_CONFIG_HOME/pacman/makepkg.conf or ~/.makepkg.conf, with the former taking priority. diff --git a/doc/pacman.8.asciidoc b/doc/pacman.8.asciidoc index 345405d4..3ea1fef1 100644 --- a/doc/pacman.8.asciidoc +++ b/doc/pacman.8.asciidoc @@ -200,6 +200,10 @@ Options beginning with `file://`. Any paths or URLs passed as targets will not be modified. This allows mounted guest systems to be properly operated on. +*\--disable-sandbox*:: + Disable the default sandbox applied to the process downloading files on Linux + systems. Useful if experiencing landlock related failues while downloading + files when running a Linux kernel that does not support this feature. Transaction Options (apply to '-S', '-R' and '-U') -------------------------------------------------- diff --git a/doc/pacman.conf.5.asciidoc b/doc/pacman.conf.5.asciidoc index 9c46ce6e..b462169b 100644 --- a/doc/pacman.conf.5.asciidoc +++ b/doc/pacman.conf.5.asciidoc @@ -211,6 +211,10 @@ Options Specifies the user to switch to for downloading files. If this config option is not set then the downloads are done as the user running pacman. +*DisableSandbox*:: + Disable the default sandbox applied to the process downloading files on Linux + systems. Useful if experiencing landlock related failues while downloading + files when running a Linux kernel that does not support this feature. Repository Sections ------------------- diff --git a/doc/repo-add.8.asciidoc b/doc/repo-add.8.asciidoc index 0b8eab49..a6f77cd4 100644 --- a/doc/repo-add.8.asciidoc +++ b/doc/repo-add.8.asciidoc @@ -48,7 +48,7 @@ Common Options *-k, \--key* :: Specify a key to use when signing packages. Can also be specified using - the GPGKEY environmental variable. If not specified in either location, the + the GPGKEY environment variable. If not specified in either location, the default key from the keyring will be used. *-v, \--verify*:: diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 268f7213..1759a9a2 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -2300,6 +2300,20 @@ int alpm_option_set_parallel_downloads(alpm_handle_t *handle, unsigned int num_s /* End of parallel_downloads accessors */ /** @} */ +/** @name Accessors for sandbox + * + * By default, libalpm will sandbox the downloader process. + * @{ + */ + +/** Enables/disables the sandbox. + * @param handle the context handle + * @param disable_sandbox 0 for enabled, 1 for disabled + * @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); +/* End of disable_sandbox accessors */ +/** @} */ /* End of libalpm_options */ /** @} */ @@ -2954,10 +2968,12 @@ const char *alpm_version(void); int alpm_capabilities(void); /** Drop privileges by switching to a different user. + * @param handle the context handle * @param sandboxuser the user to switch to + * @param sandbox_path if non-NULL, restrict writes to this filesystem path * @return 0 on success, -1 on failure */ -int alpm_sandbox_setup_child(const char *sandboxuser); +int alpm_sandbox_setup_child(alpm_handle_t *handle, const char *sandboxuser, const char *sandbox_path); /* End of libalpm_misc */ /** @} */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 57e6f628..48993555 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -413,14 +413,13 @@ static void curl_set_handle_opts(CURL *curl, struct dload_payload *payload) curl_easy_setopt(curl, CURLOPT_USERAGENT, useragent); } - if(!payload->force && payload->destfile_name && - stat(payload->destfile_name, &st) == 0) { + if(!payload->force && payload->mtime_existing_file) { /* start from scratch, but only download if our local is out of date. */ curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); - curl_easy_setopt(curl, CURLOPT_TIMEVALUE, (long)st.st_mtime); + curl_easy_setopt(curl, CURLOPT_TIMEVALUE, payload->mtime_existing_file); _alpm_log(handle, ALPM_LOG_DEBUG, "%s: using time condition %ld\n", - payload->remote_name, (long)st.st_mtime); + payload->remote_name, (long)payload->mtime_existing_file); } else if(stat(payload->tempfile_name, &st) == 0 && payload->allow_resume) { /* a previous partial download exists, resume from end of file. */ payload->tempfile_openmode = "ab"; @@ -960,7 +959,7 @@ static int curl_download_internal_sandboxed(alpm_handle_t *handle, _alpm_log(handle, ALPM_LOG_ERROR, _("could not chdir to download directory %s\n"), localpath); ret = -1; } else { - ret = alpm_sandbox_setup_child(handle->sandboxuser); + ret = alpm_sandbox_setup_child(handle, handle->sandboxuser, localpath); if (ret != 0) { _alpm_log(handle, ALPM_LOG_ERROR, _("switching to sandbox user '%s' failed!\n"), handle->sandboxuser); _Exit(2); @@ -1141,7 +1140,10 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp FREE(sig_filename); if(ret == -1) { - returnvalue = -1; + /* ignore error if the file already existed - only signature file was downloaded */ + if(payload->mtime_existing_file == 0) { + returnvalue = -1; + } } } } @@ -1160,11 +1162,20 @@ static void prepare_resumable_downloads(alpm_list_t *payloads, const char *local alpm_list_t *p; for(p = payloads; p; p = p->next) { struct dload_payload *payload = p->data; + if(payload->destfile_name) { + const char *destfilename = mbasename(payload->destfile_name); + char *dest = _alpm_get_fullpath(localpath, destfilename, ""); + struct stat deststat; + if(stat(dest, &deststat) == 0 && deststat.st_size != 0) { + payload->mtime_existing_file = deststat.st_mtime; + } + FREE(dest); + } if(!payload->tempfile_name) { continue; - } + } const char *filename = mbasename(payload->tempfile_name); - char *src = _alpm_get_fullpath(localpath, filename, "");; + char *src = _alpm_get_fullpath(localpath, filename, ""); struct stat st; if(stat(src, &st) != 0 || st.st_size == 0) { FREE(src); @@ -1271,7 +1282,7 @@ download_signature: ret = updated ? 0 : 1; } - if (finalize_download_locations(payloads, localpath) != 0) { + if (finalize_download_locations(payloads, localpath) != 0 && ret == 0) { return -1; } return ret; diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index acaf0898..19f55749 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -42,6 +42,8 @@ struct dload_payload { alpm_list_t *cache_servers; alpm_list_t *servers; long respcode; + /* the mtime of the existing version of this file, if there is one */ + long mtime_existing_file; off_t initial_size; off_t max_size; off_t prevprogress; diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 2d360f46..e2f919f6 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -951,3 +951,11 @@ int SYMEXPORT alpm_option_set_parallel_downloads(alpm_handle_t *handle, handle->parallel_downloads = num_streams; return 0; } + +int SYMEXPORT alpm_option_set_disable_sandbox(alpm_handle_t *handle, + unsigned short disable_sandbox) +{ + CHECK_HANDLE(handle, return -1); + handle->disable_sandbox = disable_sandbox; + return 0; +} diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 63efc3d0..37724344 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -65,6 +65,7 @@ struct _alpm_handle_t { #endif unsigned short disable_dl_timeout; + unsigned short disable_sandbox; unsigned int parallel_downloads; /* number of download streams */ #ifdef HAVE_LIBGPGME diff --git a/lib/libalpm/meson.build b/lib/libalpm/meson.build index 224fbf5f..1a6672da 100644 --- a/lib/libalpm/meson.build +++ b/lib/libalpm/meson.build @@ -25,6 +25,7 @@ libalpm_sources = files(''' rawstr.c remove.h remove.c sandbox.h sandbox.c + sandbox_fs.h sandbox_fs.c signing.c signing.h sync.h sync.c trans.h trans.c diff --git a/lib/libalpm/sandbox.c b/lib/libalpm/sandbox.c index 0f3d7084..d8e01e44 100644 --- a/lib/libalpm/sandbox.c +++ b/lib/libalpm/sandbox.c @@ -1,7 +1,7 @@ /* * sandbox.c * - * Copyright (c) 2021-2022 Pacman Development Team + * Copyright (c) 2021-2024 Pacman Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,15 +26,19 @@ #include "alpm.h" #include "log.h" #include "sandbox.h" +#include "sandbox_fs.h" #include "util.h" -int SYMEXPORT alpm_sandbox_setup_child(const char* sandboxuser) +int SYMEXPORT alpm_sandbox_setup_child(alpm_handle_t *handle, const char* sandboxuser, const char* sandbox_path) { struct passwd const *pw = NULL; ASSERT(sandboxuser != NULL, return -1); ASSERT(getuid() == 0, return -1); ASSERT((pw = getpwnam(sandboxuser)), return -1); + if(sandbox_path != NULL && !handle->disable_sandbox) { + _alpm_sandbox_fs_restrict_writes_to(handle, sandbox_path); + } ASSERT(setgid(pw->pw_gid) == 0, return -1); ASSERT(setgroups(0, NULL) == 0, return -1); ASSERT(setuid(pw->pw_uid) == 0, return -1); diff --git a/lib/libalpm/sandbox_fs.c b/lib/libalpm/sandbox_fs.c new file mode 100644 index 00000000..3d7de013 --- /dev/null +++ b/lib/libalpm/sandbox_fs.c @@ -0,0 +1,173 @@ +/* + * sandbox_fs.c + * + * Copyright (c) 2021-2024 Pacman Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +#include "config.h" +#include "log.h" +#include "sandbox_fs.h" +#include "util.h" + +#ifdef HAVE_LINUX_LANDLOCK_H +# include +# include +# include +#endif /* HAVE_LINUX_LANDLOCK_H */ + +#ifdef HAVE_LINUX_LANDLOCK_H +#ifndef landlock_create_ruleset +static inline int landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, + const size_t size, const __u32 flags) +{ + return syscall(__NR_landlock_create_ruleset, attr, size, flags); +} +#endif /* landlock_create_ruleset */ + +#ifndef landlock_add_rule +static inline int landlock_add_rule(const int ruleset_fd, + const enum landlock_rule_type rule_type, + const void *const rule_attr, const __u32 flags) +{ + return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, flags); +} +#endif /* landlock_add_rule */ + +#ifndef landlock_restrict_self +static inline int landlock_restrict_self(const int ruleset_fd, const __u32 flags) +{ + return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); +} +#endif /* landlock_restrict_self */ + +#define _LANDLOCK_ACCESS_FS_WRITE ( \ + LANDLOCK_ACCESS_FS_WRITE_FILE | \ + LANDLOCK_ACCESS_FS_REMOVE_DIR | \ + LANDLOCK_ACCESS_FS_REMOVE_FILE | \ + LANDLOCK_ACCESS_FS_MAKE_CHAR | \ + LANDLOCK_ACCESS_FS_MAKE_DIR | \ + LANDLOCK_ACCESS_FS_MAKE_REG | \ + LANDLOCK_ACCESS_FS_MAKE_SOCK | \ + LANDLOCK_ACCESS_FS_MAKE_FIFO | \ + LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ + LANDLOCK_ACCESS_FS_MAKE_SYM) + +#define _LANDLOCK_ACCESS_FS_READ ( \ + LANDLOCK_ACCESS_FS_READ_FILE | \ + LANDLOCK_ACCESS_FS_READ_DIR) + +#ifdef LANDLOCK_ACCESS_FS_REFER +#define _LANDLOCK_ACCESS_FS_REFER LANDLOCK_ACCESS_FS_REFER +#else +#define _LANDLOCK_ACCESS_FS_REFER 0 +#endif /* LANDLOCK_ACCESS_FS_REFER */ + +#ifdef LANDLOCK_ACCESS_FS_TRUNCATE +#define _LANDLOCK_ACCESS_FS_TRUNCATE LANDLOCK_ACCESS_FS_TRUNCATE +#else +#define _LANDLOCK_ACCESS_FS_TRUNCATE 0 +#endif /* LANDLOCK_ACCESS_FS_TRUNCATE */ + +#endif /* HAVE_LINUX_LANDLOCK_H */ + +bool _alpm_sandbox_fs_restrict_writes_to(alpm_handle_t *handle, const char *path) +{ + ASSERT(handle != NULL, return false); + ASSERT(path != NULL, return false); + +#ifdef HAVE_LINUX_LANDLOCK_H + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = \ + _LANDLOCK_ACCESS_FS_READ | \ + _LANDLOCK_ACCESS_FS_WRITE | \ + _LANDLOCK_ACCESS_FS_REFER | \ + _LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_EXECUTE, + }; + struct landlock_path_beneath_attr path_beneath = { + .allowed_access = _LANDLOCK_ACCESS_FS_READ, + }; + int abi = 0; + int result = 0; + int ruleset_fd; + + abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); + if(abi < 0) { + /* landlock is not supported/enabled in the kernel */ + _alpm_log(handle, ALPM_LOG_ERROR, _("restricting filesystem access failed because landlock is not supported by the kernel!\n")); + return true; + } +#ifdef LANDLOCK_ACCESS_FS_REFER + if(abi < 2) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("landlock ABI < 2, LANDLOCK_ACCESS_FS_REFER is not supported\n")); + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER; + } +#endif /* LANDLOCK_ACCESS_FS_REFER */ +#ifdef LANDLOCK_ACCESS_FS_TRUNCATE + if(abi < 3) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("landlock ABI < 3, LANDLOCK_ACCESS_FS_TRUNCATE is not supported\n")); + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE; + } +#endif /* LANDLOCK_ACCESS_FS_TRUNCATE */ + + ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + if(ruleset_fd < 0) { + _alpm_log(handle, ALPM_LOG_ERROR, _("restricting filesystem access failed because the landlock ruleset could not be created!\n")); + return false; + } + + /* allow / as read-only */ + path_beneath.parent_fd = open("/", O_PATH | O_CLOEXEC | O_DIRECTORY); + path_beneath.allowed_access = _LANDLOCK_ACCESS_FS_READ; + + if(landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0) != 0) { + _alpm_log(handle, ALPM_LOG_ERROR, _("restricting filesystem access failed because the landlock rule for / could not be added!\n")); + close(path_beneath.parent_fd); + close(ruleset_fd); + return false; + } + + close(path_beneath.parent_fd); + + /* allow read-write access to the directory passed as parameter */ + path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC | O_DIRECTORY); + path_beneath.allowed_access = _LANDLOCK_ACCESS_FS_READ | _LANDLOCK_ACCESS_FS_WRITE | _LANDLOCK_ACCESS_FS_TRUNCATE; + + if(!landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0) != 0) { + if(landlock_restrict_self(ruleset_fd, 0)) { + _alpm_log(handle, ALPM_LOG_ERROR, _("restricting filesystem access failed because the landlock ruleset could not be applied!\n")); + result = errno; + } + } else { + result = errno; + _alpm_log(handle, ALPM_LOG_ERROR, _("restricting filesystem access failed because the landlock rule for the temporary download directory could not be added!\n")); + } + + close(path_beneath.parent_fd); + close(ruleset_fd); + if(result == 0) { + _alpm_log(handle, ALPM_LOG_DEBUG, _("filesystem access has been restricted to %s, landlock ABI is %d\n"), path, abi); + return true; + } + return false; +#else /* HAVE_LINUX_LANDLOCK_H */ + return true; +#endif /* HAVE_LINUX_LANDLOCK_H */ +} diff --git a/lib/libalpm/sandbox_fs.h b/lib/libalpm/sandbox_fs.h new file mode 100644 index 00000000..70bfa157 --- /dev/null +++ b/lib/libalpm/sandbox_fs.h @@ -0,0 +1,27 @@ +/* + * sandbox_fs.h + * + * Copyright (c) 2021-2024 Pacman Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef ALPM_SANDBOX_FS_H +#define ALPM_SANDBOX_FS_H + +#include +#include "alpm.h" + +bool _alpm_sandbox_fs_restrict_writes_to(alpm_handle_t *handle, const char *path); + +#endif /* ALPM_SANDBOX_FS_H */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 3e87d574..9e5c28a4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -805,7 +805,7 @@ static int download_files(alpm_handle_t *handle) for(i = files, idx = 0; i; i = i->next, idx++) { const alpm_pkg_t *pkg = i->data; - file_sizes[idx] = pkg->size; + file_sizes[idx] = pkg->download_size; } ret = _alpm_check_downloadspace(handle, temporary_cachedir, num_files, file_sizes); diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 4892820b..ef77e792 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -337,7 +337,7 @@ static int grep(const char *fn, const char *needle) int _alpm_runscriptlet(alpm_handle_t *handle, const char *filepath, const char *script, const char *ver, const char *oldver, int is_archive) { - char arg0[64], arg1[3], cmdline[PATH_MAX]; + char arg0[PATH_MAX], arg1[3], cmdline[PATH_MAX]; char *argv[] = { arg0, arg1, cmdline, NULL }; char *tmpdir, *scriptfn = NULL, *scriptpath; int retval = 0; diff --git a/meson.build b/meson.build index bc2ef468..21b8cede 100644 --- a/meson.build +++ b/meson.build @@ -123,6 +123,7 @@ else endif foreach header : [ + 'linux/landlock.h', 'mntent.h', 'sys/mnttab.h', 'sys/mount.h', diff --git a/scripts/libmakepkg/autodep/library_depends.sh.in b/scripts/libmakepkg/autodep/library_depends.sh.in index c088baff..6f58781b 100644 --- a/scripts/libmakepkg/autodep/library_depends.sh.in +++ b/scripts/libmakepkg/autodep/library_depends.sh.in @@ -60,7 +60,7 @@ library_depends() { continue fi - # only add library dependency if it exists - this helps bootstraping dependencies + # only add library dependency if it exists - this helps bootstrapping dependencies if [[ $(run_pacman -T "$prefix:$sofile") ]]; then continue fi diff --git a/scripts/libmakepkg/source/git.sh.in b/scripts/libmakepkg/source/git.sh.in index e8051760..5f700a09 100644 --- a/scripts/libmakepkg/source/git.sh.in +++ b/scripts/libmakepkg/source/git.sh.in @@ -49,7 +49,7 @@ download_git() { if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "git" - if ! git clone --origin=origin ${GITFLAGS:---mirror} "$url" "$dir"; then + if ! git clone --origin=origin ---mirror "$url" "$dir"; then error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "git" plainerr "$(gettext "Aborting...")" exit 1 @@ -100,7 +100,7 @@ extract_git() { exit 1 fi cd_safe "$srcdir" - elif ! git -C "$dir" worktree add --force "${srcdir}/${dir##*/}"; then + elif ! git clone --origin=origin -s "$dir" "${dir##*/}"; then error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git" plainerr "$(gettext "Aborting...")" exit 1 diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index db359167..0b44004c 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -60,7 +60,7 @@ package_source_files() { file="${srcdir}/${t}" dest="${dbgsrc}/${t}" mkdir -p "${dest%/*}" - if [[ -f "$file" ]]; then + if [[ -f "$file" && ! -f "$dest" ]]; then cp -- "$file" "$dest" fi done < <(source_files "$binary") diff --git a/scripts/libmakepkg/util/config.sh.in b/scripts/libmakepkg/util/config.sh.in index e9bb7044..63f16d66 100644 --- a/scripts/libmakepkg/util/config.sh.in +++ b/scripts/libmakepkg/util/config.sh.in @@ -77,5 +77,8 @@ load_makepkg_config() { source_makepkg_config "$MAKEPKG_CONF" + # prevent PKGBUILDs altering this directly + readonly -a BUILDENV + eval "$restore_envvars" } diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index e74e987e..75df3650 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -87,6 +87,8 @@ else fi export SOURCE_DATE_EPOCH +MAKEPKG_LINT_PKGBUILD=${MAKEPKG_LINT_PKGBUILD:-1} + PACMAN_OPTS=() shopt -s extglob @@ -241,7 +243,7 @@ run_pacman() { cmd=("${PACMAN_AUTH[@]}" "${cmd[@]}") fi elif type -p sudo >/dev/null; then - cmd=(sudo "${cmd[@]}") + cmd=(sudo -k "${cmd[@]}") else cmd=(su root -c "$cmdescape") fi @@ -713,7 +715,7 @@ create_srcpackage() { done pkgname=(${pkgname_backup[@]}) - # add a copy of source PGP signing public keys if availabe in keys/pgp/.asc + # add a copy of source PGP signing public keys if available in keys/pgp/.asc local key for key in ${validpgpkeys[@]}; do if [[ -f keys/pgp/$key.asc ]]; then @@ -1151,7 +1153,9 @@ fi pkgbase=${pkgbase:-${pkgname[0]}} # check the PKGBUILD for some basic requirements -lint_pkgbuild || exit $E_PKGBUILD_ERROR +if (( MAKEPKG_LINT_PKGBUILD != 0 )); then + lint_pkgbuild || exit $E_PKGBUILD_ERROR +fi if (( !SOURCEONLY && !PRINTSRCINFO )); then merge_arch_attrs diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 2cf56bf1..d0966eea 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -218,7 +218,7 @@ static char *get_tempfile(const char *path, const char *filename) * - not thread-safe * - errno may be set by fork(), pipe(), or execvp() */ -static int systemvp(const char *file, char *const argv[], const char *sandboxuser) +static int systemvp(const char *file, char *const argv[]) { int pid, err = 0, ret = -1, err_fd[2]; sigset_t oldblock; @@ -245,10 +245,10 @@ static int systemvp(const char *file, char *const argv[], const char *sandboxuse sigaction(SIGQUIT, &oldquit, NULL); sigprocmask(SIG_SETMASK, &oldblock, NULL); - if (sandboxuser) { - ret = alpm_sandbox_setup_child(sandboxuser); + if (config->sandboxuser) { + ret = alpm_sandbox_setup_child(config->handle, config->sandboxuser, NULL); if (ret != 0) { - pm_printf(ALPM_LOG_ERROR, _("switching to sandbox user '%s' failed!\n"), sandboxuser); + pm_printf(ALPM_LOG_ERROR, _("switching to sandbox user '%s' failed!\n"), config->sandboxuser); _Exit(ret); } } @@ -363,7 +363,7 @@ static int download_with_xfercommand(void *ctx, const char *url, free(cmd); } } - retval = systemvp(argv[0], (char**)argv, config->sandboxuser); + retval = systemvp(argv[0], (char**)argv); if(retval == -1) { pm_printf(ALPM_LOG_WARNING, _("running XferCommand: fork failed!\n")); @@ -629,6 +629,8 @@ 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, "DisableSandbox") == 0) { + config->disable_sandbox = 1; } else { pm_printf(ALPM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), @@ -937,6 +939,7 @@ static int setup_libalpm(void) alpm_option_set_checkspace(handle, config->checkspace); alpm_option_set_usesyslog(handle, config->usesyslog); alpm_option_set_sandboxuser(handle, config->sandboxuser); + alpm_option_set_disable_sandbox(handle, config->disable_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 e9f17123..5bffd187 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -58,6 +58,7 @@ typedef struct __config_t { unsigned short usesyslog; unsigned short color; unsigned short disable_dl_timeout; + unsigned short disable_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 @@ -212,7 +213,8 @@ enum { OP_DOWNLOADONLY, OP_REFRESH, OP_ASSUMEINSTALLED, - OP_DISABLEDLTIMEOUT + OP_DISABLEDLTIMEOUT, + OP_DISABLESANDBOX }; /* clean method */ diff --git a/src/pacman/pacman-conf.c b/src/pacman/pacman-conf.c index d73d6c4c..92e68003 100644 --- a/src/pacman/pacman-conf.c +++ b/src/pacman/pacman-conf.c @@ -280,6 +280,7 @@ static void dump_config(void) show_bool("DisableDownloadTimeout", config->disable_dl_timeout); show_bool("ILoveCandy", config->chomp); show_bool("NoProgressBar", config->noprogressbar); + show_bool("DisableSandbox", config->disable_sandbox); show_int("ParallelDownloads", config->parallel_downloads); @@ -397,6 +398,8 @@ 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, "DisableSandbox") == 0) { + show_bool("DisableSandbox", config->disable_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 6b64ffc7..90d37b16 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -226,6 +226,8 @@ static void usage(int op, const char * const myname) addlist(_(" --confirm always ask for confirmation\n")); addlist(_(" --disable-download-timeout\n" " use relaxed timeouts for download\n")); + addlist(_(" --disable-sandbox\n" + " disable 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)) { @@ -490,6 +492,9 @@ static int parsearg_global(int opt) case OP_DISABLEDLTIMEOUT: config->disable_dl_timeout = 1; break; + case OP_DISABLESANDBOX: + config->disable_sandbox = 1; + break; case OP_VERBOSE: case 'v': (config->verbose)++; @@ -976,6 +981,7 @@ 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-sandbox", no_argument, 0, OP_DISABLESANDBOX}, {0, 0, 0, 0} }; diff --git a/test/pacman/ChangeLog b/test/pacman/ChangeLog index eb097084..1e92c3e0 100644 --- a/test/pacman/ChangeLog +++ b/test/pacman/ChangeLog @@ -16,7 +16,7 @@ Release 0.2 (06/02/13) ----------- - added support for directories, symlinks and altered files - removed hardcoded references to package names in testcase scripts -- splited pactest.py in several modules +- split pactest.py in several modules - lots of code optimizations - created a home page to host the project - added README, TODO and ChangeLog files diff --git a/test/pacman/tests/symlink020.py b/test/pacman/tests/symlink020.py index 343add2d..c8c0cae8 100644 --- a/test/pacman/tests/symlink020.py +++ b/test/pacman/tests/symlink020.py @@ -1,4 +1,4 @@ -self.description = "symlink -> dir replacment" +self.description = "symlink -> dir replacement" lp1 = pmpkg("pkg1") lp1.files = ["usr/lib/foo", diff --git a/test/pacman/tests/symlink021.py b/test/pacman/tests/symlink021.py index 1ba7c025..0baca727 100644 --- a/test/pacman/tests/symlink021.py +++ b/test/pacman/tests/symlink021.py @@ -1,4 +1,4 @@ -self.description = "symlink -> dir replacment with file move" +self.description = "symlink -> dir replacement with file move" lp1 = pmpkg("pkg1") lp1.files = ["usr/include/foo/",