XBPS Library API 20240111
The X Binary Package System
fexec.c
1/*-
2 * Copyright (c) 2003 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Matthias Scheler.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <sys/wait.h>
33
34#include <errno.h>
35#include <stdarg.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39
40#include "xbps_api_impl.h"
41
42static int
43pfcexec(struct xbps_handle *xhp, const char *file, const char **argv)
44{
45 pid_t child;
46 int status;
47
48 child = fork();
49 switch (child) {
50 case 0:
51 /*
52 * If rootdir != / and uid==0 and bin/sh exists,
53 * change root directory and exec command.
54 */
55 if (strcmp(xhp->rootdir, "/")) {
56 if ((geteuid() == 0) && (access("bin/sh", X_OK) == 0)) {
57 if (chroot(xhp->rootdir) == -1) {
58 xbps_dbg_printf("%s: chroot() "
59 "failed: %s\n", *argv, strerror(errno));
60 _exit(errno);
61 }
62 if (chdir("/") == -1) {
63 xbps_dbg_printf("%s: chdir() "
64 "failed: %s\n", *argv, strerror(errno));
65 _exit(errno);
66 }
67 }
68 }
69 umask(022);
70 (void)execv(file, __UNCONST(argv));
71 _exit(errno);
72 /* NOTREACHED */
73 case -1:
74 return -1;
75 }
76
77 while (waitpid(child, &status, 0) < 0) {
78 if (errno != EINTR)
79 return -1;
80 }
81
82 if (!WIFEXITED(status))
83 return -1;
84
85 return WEXITSTATUS(status);
86}
87
88static int
89vfcexec(struct xbps_handle *xhp, const char *arg, va_list ap)
90{
91 const char **argv;
92 size_t argv_size, argc;
93 int retval;
94
95 argv_size = 16;
96 if ((argv = malloc(argv_size * sizeof(*argv))) == NULL) {
97 errno = ENOMEM;
98 return -1;
99 }
100
101 argv[0] = arg;
102 argc = 1;
103
104 do {
105 if (argc == argv_size) {
106 argv_size *= 2;
107 argv = realloc(argv, argv_size * sizeof(*argv));
108 if (argv == NULL) {
109 errno = ENOMEM;
110 return -1;
111 }
112 }
113
114 arg = va_arg(ap, const char *);
115 argv[argc++] = arg;
116
117 } while (arg != NULL);
118
119 retval = pfcexec(xhp, argv[0], argv);
120 free(argv);
121
122 return retval;
123}
124
125int HIDDEN
126xbps_file_exec(struct xbps_handle *xhp, const char *arg, ...)
127{
128 va_list ap;
129 int result;
130
131 va_start(ap, arg);
132 result = vfcexec(xhp, arg, ap);
133 va_end(ap);
134
135 return result;
136}
char rootdir[XBPS_MAXPATH]
Definition xbps.h:650
Generic XBPS structure handler for initialization.
Definition xbps.h:550