From a94dd5dbfa60872f0b2d2d3b845ac77694ef966b Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 30 May 2012 17:26:25 +0200 Subject: [PATCH] Revert "libxbps: implement xbps_file_exec() with posix_spawn()." This reverts commit 5aa05f4c72bc619b5ac99ce0879fc52fc7aa2d23. --- 3RDPARTY | 2 + COPYING | 2 +- NEWS | 3 - configure | 22 ----- include/xbps_api.h | 2 +- include/xbps_api_impl.h | 4 +- lib/Makefile | 4 +- lib/external/fexec.c | 173 ++++++++++++++++++++++++++++++++++++++++ lib/file_exec.c | 108 ------------------------- 9 files changed, 182 insertions(+), 138 deletions(-) create mode 100644 lib/external/fexec.c delete mode 100644 lib/file_exec.c diff --git a/3RDPARTY b/3RDPARTY index fce689fc..96dd6811 100644 --- a/3RDPARTY +++ b/3RDPARTY @@ -13,6 +13,8 @@ internal use in the code: - mkpath from NetBSD's mkdir(1): lib/external/mkpath.c +- fexec from NetBSD's pkg_install: lib/external/fexec.c + - libfetch-2.31 from NetBSD: lib/fetch - portableproplib-0.4.1 (lib/portableproplib) from diff --git a/COPYING b/COPYING index 877fbe27..4d190250 100644 --- a/COPYING +++ b/COPYING @@ -140,7 +140,7 @@ This product uses some code with the following license */ This product uses some code with the following license -(lib/humanize_number.c): +(lib/humanize_number.c, lib/fexec.c): /* * Copyright (c) 2003 The NetBSD Foundation, Inc. diff --git a/NEWS b/NEWS index 504c5366..2054a147 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,5 @@ xbps-0.16 (???): - * libxbps: implemented xbps_file_exec thru posix_spawn. That means - posix_spawn() is now required in xbps. - * libxbps: renamed xbps_repository_pool_xxx to xbps_rpool_xxx (API/ABI incompat changes). diff --git a/configure b/configure index 6fc9d4b7..1f48f5cf 100755 --- a/configure +++ b/configure @@ -305,28 +305,6 @@ if [ -n "$BUILD_PIE" ]; then fi fi -# -# Check for posix_spawn (required). -# -func=posix_spawn -printf "Checking for $func() ... " -cat < _$func.c -#include -#include -int main(void) { - posix_spawn(NULL, NULL, NULL, NULL, NULL, NULL); - return 0; -} -EOF -if $XCC _${func}.c -o _${func} 2>/dev/null; then - rm -f _$func.c _$func - echo "yes." -else - echo "not found! $func is required by xbps, exiting..." - rm -f _$func.c _$func - exit 1 -fi - # # Check for vasprintf(). # diff --git a/include/xbps_api.h b/include/xbps_api.h index 90cd32fe..56e60f5b 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -56,7 +56,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.4" -#define XBPS_API_VERSION "20120530-3" +#define XBPS_API_VERSION "20120530-2" #define XBPS_VERSION "0.16" /** diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index 0f8a7f40..15e4b51b 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -165,9 +165,11 @@ char HIDDEN *xbps_get_remote_repo_string(const char *); /** * @private - * From lib/file_exec.c + * From lib/fexec.c */ int HIDDEN xbps_file_exec(const char *, ...); +int HIDDEN xbps_file_exec_skipempty(const char *, ...); +int HIDDEN xbps_file_chdir_exec(const char *, const char *, ...); /** * @private diff --git a/lib/Makefile b/lib/Makefile index ad48a46a..86335fb5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -37,7 +37,7 @@ LIBFETCH_OBJS = endif # External code used by libxbps -EXTOBJS = external/dewey.o external/humanize_number.o +EXTOBJS = external/dewey.o external/fexec.o external/humanize_number.o EXTOBJS += external/match.o external/mkpath.o # libxbps @@ -46,7 +46,7 @@ OBJS += package_remove.o package_remove_obsoletes.o package_state.o OBJS += package_unpack.o package_requiredby.o package_register.o OBJS += transaction_commit.o transaction_package_replace.o OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.o -OBJS += download.o initend.o pkgdb.o file_exec.o +OBJS += download.o initend.o pkgdb.o OBJS += plist.o plist_archive_entry.o plist_find.o plist_match.o OBJS += plist_remove.o plist_fetch.o util.o util_hash.o OBJS += repository_finddeps.o cb_util.o diff --git a/lib/external/fexec.c b/lib/external/fexec.c new file mode 100644 index 00000000..613eecca --- /dev/null +++ b/lib/external/fexec.c @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xbps_api_impl.h" + +static int +pfcexec(const char *path, const char *file, const char **argv) +{ + pid_t child; + int status; + bool do_chroot = false; + + child = vfork(); + switch (child) { + case 0: + if (getuid() == 0 && access("./bin/sh", X_OK) == 0) + do_chroot = true; + + /* + * If uid==0 and /bin/sh exists, we can change root directory, + * fork and execute the command. Otherwise just change current + * directory and fork/execute. + */ + if (path && do_chroot) { + if (chroot(path) == -1) + _exit(127); + if (chdir("/") == -1) + _exit(127); + } else if (path && !do_chroot) { + if (chdir(path) == -1) + _exit(127); + } else if (path == NULL && do_chroot) { + if (chroot(".") == -1) { + if (errno != EPERM) + _exit(127); + if (chdir(".") == -1) + _exit(127); + } else { + if (chdir("/") == -1) + _exit(127); + } + } + + (void)execv(file, __UNCONST(argv)); + _exit(127); + /* NOTREACHED */ + case -1: + return -1; + } + + while (waitpid(child, &status, 0) < 0) { + if (errno != EINTR) + return -1; + } + + if (!WIFEXITED(status)) + return -1; + + return WEXITSTATUS(status); +} + +static int +vfcexec(const char *path, int skipempty, const char *arg, va_list ap) +{ + const char **argv; + size_t argv_size, argc; + int retval; + + argv_size = 16; + if ((argv = malloc(argv_size * sizeof(*argv))) == NULL) { + errno = ENOMEM; + return -1; + } + + argv[0] = arg; + argc = 1; + + do { + if (argc == argv_size) { + argv_size *= 2; + argv = realloc(argv, argv_size * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return -1; + } + } + + arg = va_arg(ap, const char *); + if (skipempty && arg && strlen(arg) == 0) + continue; + + argv[argc++] = arg; + + } while (arg != NULL); + + retval = pfcexec(path, argv[0], argv); + free(argv); + + return retval; +} + +int HIDDEN +xbps_file_exec(const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(NULL, 0, arg, ap); + va_end(ap); + + return result; +} + +int HIDDEN +xbps_file_exec_skipempty(const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(NULL, 1, arg, ap); + va_end(ap); + + return result; +} + +int HIDDEN +xbps_file_chdir_exec(const char *path, const char *arg, ...) +{ + va_list ap; + int result; + + va_start(ap, arg); + result = vfcexec(path, 0, arg, ap); + va_end(ap); + + return result; +} diff --git a/lib/file_exec.c b/lib/file_exec.c deleted file mode 100644 index 93b92159..00000000 --- a/lib/file_exec.c +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2012 Juan Romero Pardines. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xbps_api_impl.h" - -static int -pfcexec(const char *file, const char **argv) -{ - pid_t child; - int status, rv; - - if (((getuid() == 0) && (access("bin/sh", X_OK) == 0))) { - if ((chroot(".") != 0) && (chdir("/") != 0)) - return errno; - } - if ((rv = posix_spawn(&child, file, NULL, NULL, - (char ** const)__UNCONST(argv), - NULL)) == 0) { - while (waitpid(child, &status, 0) < 0) { - if (errno != EINTR) - return errno; - } - if (!WIFEXITED(status)) - return errno; - - return WEXITSTATUS(status); - } - return rv; -} - -static int -vfcexec(const char *arg, va_list ap) -{ - const char **argv; - size_t argv_size, argc; - int retval; - - argv_size = 16; - if ((argv = malloc(argv_size * sizeof(*argv))) == NULL) { - errno = ENOMEM; - return -1; - } - argv[0] = arg; - argc = 1; - - do { - if (argc == argv_size) { - argv_size *= 2; - argv = realloc(argv, argv_size * sizeof(*argv)); - if (argv == NULL) { - errno = ENOMEM; - return -1; - } - } - arg = va_arg(ap, const char *); - argv[argc++] = arg; - - } while (arg != NULL); - - retval = pfcexec(argv[0], argv); - free(argv); - - return retval; -} - -int HIDDEN -xbps_file_exec(const char *arg, ...) -{ - va_list ap; - int result; - - va_start(ap, arg); - result = vfcexec(arg, ap); - va_end(ap); - - return result; -}