OpenCoverage

chroot.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/src/chroot.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* chroot -- run command or shell with special root directory-
2 Copyright (C) 1995-2018 Free Software Foundation, Inc.-
3-
4 This program is free software: you can redistribute it and/or modify-
5 it under the terms of the GNU General Public License as published by-
6 the Free Software Foundation, either version 3 of the License, or-
7 (at your option) any later version.-
8-
9 This program is distributed in the hope that it will be useful,-
10 but WITHOUT ANY WARRANTY; without even the implied warranty of-
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
12 GNU General Public License for more details.-
13-
14 You should have received a copy of the GNU General Public License-
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
16-
17/* Written by Roland McGrath. */-
18-
19#include <config.h>-
20#include <getopt.h>-
21#include <stdio.h>-
22#include <sys/types.h>-
23#include <pwd.h>-
24#include <grp.h>-
25-
26#include "system.h"-
27#include "die.h"-
28#include "error.h"-
29#include "ignore-value.h"-
30#include "mgetgroups.h"-
31#include "quote.h"-
32#include "root-dev-ino.h"-
33#include "userspec.h"-
34#include "xstrtol.h"-
35-
36/* The official name of this program (e.g., no 'g' prefix). */-
37#define PROGRAM_NAME "chroot"-
38-
39#define AUTHORS proper_name ("Roland McGrath")-
40-
41#ifndef MAXGID-
42# define MAXGID GID_T_MAX-
43#endif-
44-
45static
never executed: return uid == (uid_t) -1;
inline bool uid_unset (uid_t uid) { return uid == (uid_t) -1; }
never executed: return uid == (uid_t) -1;
0
46static
never executed: return gid == (gid_t) -1;
inline bool gid_unset (gid_t gid) { return gid == (gid_t) -1; }
never executed: return gid == (gid_t) -1;
0
47#define uid_set(x) (!uid_unset (x))-
48#define gid_set(x) (!gid_unset (x))-
49-
50enum-
51{-
52 GROUPS = UCHAR_MAX + 1,-
53 USERSPEC,-
54 SKIP_CHDIR-
55};-
56-
57static struct option const long_opts[] =-
58{-
59 {"groups", required_argument, NULL, GROUPS},-
60 {"userspec", required_argument, NULL, USERSPEC},-
61 {"skip-chdir", no_argument, NULL, SKIP_CHDIR},-
62 {GETOPT_HELP_OPTION_DECL},-
63 {GETOPT_VERSION_OPTION_DECL},-
64 {NULL, 0, NULL, 0}-
65};-
66-
67#if ! HAVE_SETGROUPS-
68/* At least Interix lacks supplemental group support. */-
69static int-
70setgroups (size_t size, gid_t const *list _GL_UNUSED)-
71{-
72 if (size == 0)-
73 {-
74 /* Return success when clearing supplemental groups-
75 as ! HAVE_SETGROUPS should only be the case on-
76 platforms that don't support supplemental groups. */-
77 return 0;-
78 }-
79 else-
80 {-
81 errno = ENOTSUP;-
82 return -1;-
83 }-
84}-
85#endif-
86-
87/* Determine the group IDs for the specified supplementary GROUPS,-
88 which is a comma separated list of supplementary groups (names or numbers).-
89 Allocate an array for the parsed IDs and store it in PGIDS,-
90 which may be allocated even on parse failure.-
91 Update the number of parsed groups in PN_GIDS on success.-
92 Upon any failure return nonzero, and issue diagnostic if SHOW_ERRORS is true.-
93 Otherwise return zero. */-
94-
95static int-
96parse_additional_groups (char const *groups, GETGROUPS_T **pgids,-
97 size_t *pn_gids, bool show_errors)-
98{-
99 GETGROUPS_T *gids = NULL;-
100 size_t n_gids_allocated = 0;-
101 size_t n_gids = 0;-
102 char *buffer = xstrdup (groups);-
103 char const *tmp;-
104 int ret = 0;-
105-
106 for (tmp = strtok (buffer, ","); tmp; tmp = strtok (NULL, ","))
tmpDescription
TRUEnever evaluated
FALSEnever evaluated
0
107 {-
108 struct group *g;-
109 unsigned long int value;-
110-
111 if (xstrtoul (tmp, NULL, 10, &value, "") == LONGINT_OK && value <= MAXGID)
xstrtoul (tmp,... == LONGINT_OKDescription
TRUEnever evaluated
FALSEnever evaluated
value <= ((gid... 1) * 2 + 1)))Description
TRUEnever evaluated
FALSEnever evaluated
0
112 {-
113 while (isspace (to_uchar (*tmp)))
((*__ctype_b_l...int) _ISspace)Description
TRUEnever evaluated
FALSEnever evaluated
0
114 tmp++;
never executed: tmp++;
0
115 if (*tmp != '+')
*tmp != '+'Description
TRUEnever evaluated
FALSEnever evaluated
0
116 {-
117 /* Handle the case where the name is numeric. */-
118 g = getgrnam (tmp);-
119 if (g != NULL)
g != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
120 value = g->gr_gid;
never executed: value = g->gr_gid;
0
121 }
never executed: end of block
0
122 /* Flag that we've got a group from the number. */-
123 g = (struct group *) (intptr_t) ! NULL;-
124 }
never executed: end of block
0
125 else-
126 {-
127 g = getgrnam (tmp);-
128 if (g != NULL)
g != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
129 value = g->gr_gid;
never executed: value = g->gr_gid;
0
130 }
never executed: end of block
0
131-
132 if (g == NULL)
g == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
133 {-
134 ret = -1;-
135-
136 if (show_errors)
show_errorsDescription
TRUEnever evaluated
FALSEnever evaluated
0
137 {-
138 error (0, errno, _("invalid group %s"), quote (tmp));-
139 continue;
never executed: continue;
0
140 }-
141-
142 break;
never executed: break;
0
143 }-
144-
145 if (n_gids == n_gids_allocated)
n_gids == n_gids_allocatedDescription
TRUEnever evaluated
FALSEnever evaluated
0
146 gids = X2NREALLOC (gids, &n_gids_allocated);
never executed: gids = ((void) (!!sizeof (struct { _Static_assert (sizeof *(gids) != 1, "verify_true (" "sizeof *(gids) != 1" ")"); int _gl_dummy; })), x2nrealloc (gids, &n_gids_allocated, sizeof *(gids)));
0
147 gids[n_gids++] = value;-
148 }
never executed: end of block
0
149-
150 if (ret == 0 && n_gids == 0)
ret == 0Description
TRUEnever evaluated
FALSEnever evaluated
n_gids == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
151 {-
152 if (show_errors)
show_errorsDescription
TRUEnever evaluated
FALSEnever evaluated
0
153 error (0, 0, _("invalid group list %s"), quote (groups));
never executed: error (0, 0, dcgettext (((void *)0), "invalid group list %s" , 5) , quote (groups));
0
154 ret = -1;-
155 }
never executed: end of block
0
156-
157 *pgids = gids;-
158-
159 if (ret == 0)
ret == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
160 *pn_gids = n_gids;
never executed: *pn_gids = n_gids;
0
161-
162 free (buffer);-
163 return ret;
never executed: return ret;
0
164}-
165-
166/* Return whether the passed path is equivalent to "/".-
167 Note we don't compare against get_root_dev_ino() as "/"-
168 could be bind mounted to a separate location. */-
169-
170static bool-
171is_root (const char* dir)-
172{-
173 char *resolved = canonicalize_file_name (dir);-
174 bool is_res_root = resolved && STREQ ("/", resolved);
never executed: __result = (((const unsigned char *) (const char *) ( "/" ))[3] - __s2[3]);
never executed: end of block
executed 2 times by 1 test: end of block
Executed by:
  • chroot
never executed: __result = (((const unsigned char *) (const char *) ( resolved ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
resolvedDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
( __extension_...)))); }) == 0)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEevaluated 1 time by 1 test
Evaluated by:
  • chroot
__s1_len > 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
__result == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • chroot
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-2
175 free (resolved);-
176 return is_res_root;
executed 2 times by 1 test: return is_res_root;
Executed by:
  • chroot
2
177}-
178-
179void-
180usage (int status)-
181{-
182 if (status != EXIT_SUCCESS)
status != 0Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • chroot
FALSEevaluated 6 times by 1 test
Evaluated by:
  • chroot
6
183 emit_try_help ();
executed 6 times by 1 test: end of block
Executed by:
  • chroot
6
184 else-
185 {-
186 printf (_("\-
187Usage: %s [OPTION] NEWROOT [COMMAND [ARG]...]\n\-
188 or: %s OPTION\n\-
189"), program_name, program_name);-
190-
191 fputs (_("\-
192Run COMMAND with root directory set to NEWROOT.\n\-
193\n\-
194"), stdout);-
195-
196 fputs (_("\-
197 --groups=G_LIST specify supplementary groups as g1,g2,..,gN\n\-
198"), stdout);-
199 fputs (_("\-
200 --userspec=USER:GROUP specify user and group (ID or name) to use\n\-
201"), stdout);-
202 printf (_("\-
203 --skip-chdir do not change working directory to %s\n\-
204"), quoteaf ("/"));-
205-
206 fputs (HELP_OPTION_DESCRIPTION, stdout);-
207 fputs (VERSION_OPTION_DESCRIPTION, stdout);-
208 fputs (_("\-
209\n\-
210If no command is given, run '\"$SHELL\" -i' (default: '/bin/sh -i').\n\-
211"), stdout);-
212 emit_ancillary_info (PROGRAM_NAME);-
213 }
executed 6 times by 1 test: end of block
Executed by:
  • chroot
6
214 exit (status);
executed 12 times by 1 test: exit (status);
Executed by:
  • chroot
12
215}-
216-
217int-
218main (int argc, char **argv)-
219{-
220 int c;-
221-
222 /* Input user and groups spec. */-
223 char *userspec = NULL;-
224 char const *username = NULL;-
225 char const *groups = NULL;-
226 bool skip_chdir = false;-
227-
228 /* Parsed user and group IDs. */-
229 uid_t uid = -1;-
230 gid_t gid = -1;-
231 GETGROUPS_T *out_gids = NULL;-
232 size_t n_gids = 0;-
233-
234 initialize_main (&argc, &argv);-
235 set_program_name (argv[0]);-
236 setlocale (LC_ALL, "");-
237 bindtextdomain (PACKAGE, LOCALEDIR);-
238 textdomain (PACKAGE);-
239-
240 initialize_exit_failure (EXIT_CANCELED);-
241 atexit (close_stdout);-
242-
243 while ((c = getopt_long (argc, argv, "+", long_opts, NULL)) != -1)
(c = getopt_lo... *)0) )) != -1Description
TRUEevaluated 19 times by 1 test
Evaluated by:
  • chroot
FALSEevaluated 3 times by 1 test
Evaluated by:
  • chroot
3-19
244 {-
245 switch (c)-
246 {-
247 case USERSPEC:
executed 1 time by 1 test: case USERSPEC:
Executed by:
  • chroot
1
248 {-
249 userspec = optarg;-
250 /* Treat 'user:' just like 'user'-
251 as we lookup the primary group by default-
252 (and support doing so for UIDs as well as names. */-
253 size_t userlen = strlen (userspec);-
254 if (userlen && userspec[userlen - 1] == ':')
userlenDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
userspec[userlen - 1] == ':'Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • chroot
0-1
255 userspec[userlen - 1] = '\0';
never executed: userspec[userlen - 1] = '\0';
0
256 break;
executed 1 time by 1 test: break;
Executed by:
  • chroot
1
257 }-
258-
259 case GROUPS:
executed 1 time by 1 test: case GROUPS:
Executed by:
  • chroot
1
260 groups = optarg;-
261 break;
executed 1 time by 1 test: break;
Executed by:
  • chroot
1
262-
263 case SKIP_CHDIR:
executed 2 times by 1 test: case SKIP_CHDIR:
Executed by:
  • chroot
2
264 skip_chdir = true;-
265 break;
executed 2 times by 1 test: break;
Executed by:
  • chroot
2
266-
267 case_GETOPT_HELP_CHAR;
never executed: break;
executed 6 times by 1 test: case GETOPT_HELP_CHAR:
Executed by:
  • chroot
0-6
268-
269 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
executed 5 times by 1 test: exit ( 0 );
Executed by:
  • chroot
never executed: break;
executed 5 times by 1 test: case GETOPT_VERSION_CHAR:
Executed by:
  • chroot
0-5
270-
271 default:
executed 4 times by 1 test: default:
Executed by:
  • chroot
4
272 usage (EXIT_CANCELED);-
273 }
never executed: end of block
0
274 }-
275-
276 if (argc <= optind)
argc <= optindDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEevaluated 2 times by 1 test
Evaluated by:
  • chroot
1-2
277 {-
278 error (0, 0, _("missing operand"));-
279 usage (EXIT_CANCELED);-
280 }
never executed: end of block
0
281-
282 char const *newroot = argv[optind];-
283 bool is_oldroot = is_root (newroot);-
284-
285 if (! is_oldroot && skip_chdir)
! is_oldrootDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEevaluated 1 time by 1 test
Evaluated by:
  • chroot
skip_chdirDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
0-1
286 {-
287 error (0, 0, _("option --skip-chdir only permitted if NEWROOT is old %s"),-
288 quoteaf ("/"));-
289 usage (EXIT_CANCELED);-
290 }
never executed: end of block
0
291-
292 if (! is_oldroot)
! is_oldrootDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • chroot
0-1
293 {-
294 /* We have to look up users and groups twice.-
295 - First, outside the chroot to load potentially necessary passwd/group-
296 parsing plugins (e.g. NSS);-
297 - Second, inside chroot to redo parsing in case IDs are different.-
298 Within chroot lookup is the main justification for having-
299 the --user option supported by the chroot command itself. */-
300 if (userspec)
userspecDescription
TRUEnever evaluated
FALSEnever evaluated
0
301 ignore_value (parse_user_spec (userspec, &uid, &gid, NULL, NULL));
never executed: (__extension__ ({ __typeof__ (parse_user_spec (userspec, &uid, &gid, ((void *)0) , ((void *)0) )) __x = (parse_user_spec (userspec, &uid, &gid, ((void *)0) , ((void *)0) )); (void) __x; }));
0
302-
303 /* If no gid is supplied or looked up, do so now.-
304 Also lookup the username for use with getgroups. */-
305 if (uid_set (uid) && (! groups || gid_unset (gid)))
(!uid_unset (uid))Description
TRUEnever evaluated
FALSEnever evaluated
! groupsDescription
TRUEnever evaluated
FALSEnever evaluated
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
306 {-
307 const struct passwd *pwd;-
308 if ((pwd = getpwuid (uid)))
(pwd = getpwuid (uid))Description
TRUEnever evaluated
FALSEnever evaluated
0
309 {-
310 if (gid_unset (gid))
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
311 gid = pwd->pw_gid;
never executed: gid = pwd->pw_gid;
0
312 username = pwd->pw_name;-
313 }
never executed: end of block
0
314 }
never executed: end of block
0
315-
316 if (groups && *groups)
groupsDescription
TRUEnever evaluated
FALSEnever evaluated
*groupsDescription
TRUEnever evaluated
FALSEnever evaluated
0
317 ignore_value (parse_additional_groups (groups, &out_gids, &n_gids,
never executed: (__extension__ ({ __typeof__ (parse_additional_groups (groups, &out_gids, &n_gids, 0 )) __x = (parse_additional_groups (groups, &out_gids, &n_gids, 0 )); (void) __x; })) ;
0
318 false));
never executed: (__extension__ ({ __typeof__ (parse_additional_groups (groups, &out_gids, &n_gids, 0 )) __x = (parse_additional_groups (groups, &out_gids, &n_gids, 0 )); (void) __x; })) ;
0
319#if HAVE_SETGROUPS-
320 else if (! groups && gid_set (gid) && username)
! groupsDescription
TRUEnever evaluated
FALSEnever evaluated
(!gid_unset (gid))Description
TRUEnever evaluated
FALSEnever evaluated
usernameDescription
TRUEnever evaluated
FALSEnever evaluated
0
321 {-
322 int ngroups = xgetgroups (username, gid, &out_gids);-
323 if (0 < ngroups)
0 < ngroupsDescription
TRUEnever evaluated
FALSEnever evaluated
0
324 n_gids = ngroups;
never executed: n_gids = ngroups;
0
325 }
never executed: end of block
0
326#endif-
327 }
never executed: end of block
0
328-
329 if (chroot (newroot) != 0)
chroot (newroot) != 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • chroot
FALSEnever evaluated
0-1
330 die (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
executed 1 time by 1 test: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"cannot change root directory to %s\", 5), quotearg_style (shell_escape_always_quoting_style,...iltin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "cannot change root directory to %s" , 5) , quotearg_style (shell_escape_always_quoting_style, newroot)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
Executed by:
  • chroot
1
331 quoteaf (newroot));
executed 1 time by 1 test: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"cannot change root directory to %s\", 5), quotearg_style (shell_escape_always_quoting_style,...iltin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "cannot change root directory to %s" , 5) , quotearg_style (shell_escape_always_quoting_style, newroot)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
Executed by:
  • chroot
1
332-
333 if (! skip_chdir && chdir ("/"))
! skip_chdirDescription
TRUEnever evaluated
FALSEnever evaluated
chdir ("/")Description
TRUEnever evaluated
FALSEnever evaluated
0
334 die (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"cannot chdir to root directory\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error (... "cannot chdir to root directory" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "cannot chdir to root directory" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
335-
336 if (argc == optind + 1)
argc == optind + 1Description
TRUEnever evaluated
FALSEnever evaluated
0
337 {-
338 /* No command. Run an interactive shell. */-
339 char *shell = getenv ("SHELL");-
340 if (shell == NULL)
shell == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
341 shell = bad_cast ("/bin/sh");
never executed: shell = bad_cast ("/bin/sh");
0
342 argv[0] = shell;-
343 argv[1] = bad_cast ("-i");-
344 argv[2] = NULL;-
345 }
never executed: end of block
0
346 else-
347 {-
348 /* The following arguments give the command. */-
349 argv += optind + 1;-
350 }
never executed: end of block
0
351-
352 /* Attempt to set all three: supplementary groups, group ID, user ID.-
353 Diagnose any failures. If any have failed, exit before execvp. */-
354 if (userspec)
userspecDescription
TRUEnever evaluated
FALSEnever evaluated
0
355 {-
356 char const *err = parse_user_spec (userspec, &uid, &gid, NULL, NULL);-
357-
358 if (err && uid_unset (uid) && gid_unset (gid))
errDescription
TRUEnever evaluated
FALSEnever evaluated
uid_unset (uid)Description
TRUEnever evaluated
FALSEnever evaluated
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
359 die (EXIT_CANCELED, errno, "%s", (err));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), \"%s\", (err)), assume (false))" ")"); int _gl_dummy; })) ? ((error (EXIT_CANCELED, (*__errno_location ()) , "%s", (err)), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , "%s", (err)), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
360 }
never executed: end of block
0
361-
362 /* If no gid is supplied or looked up, do so now.-
363 Also lookup the username for use with getgroups. */-
364 if (uid_set (uid) && (! groups || gid_unset (gid)))
(!uid_unset (uid))Description
TRUEnever evaluated
FALSEnever evaluated
! groupsDescription
TRUEnever evaluated
FALSEnever evaluated
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
365 {-
366 const struct passwd *pwd;-
367 if ((pwd = getpwuid (uid)))
(pwd = getpwuid (uid))Description
TRUEnever evaluated
FALSEnever evaluated
0
368 {-
369 if (gid_unset (gid))
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
370 gid = pwd->pw_gid;
never executed: gid = pwd->pw_gid;
0
371 username = pwd->pw_name;-
372 }
never executed: end of block
0
373 else if (gid_unset (gid))
gid_unset (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
374 {-
375 die (EXIT_CANCELED, errno,-
376 _("no group specified for unknown uid: %d"), (int) uid);-
377 }
never executed: end of block
0
378 }
never executed: end of block
0
379-
380 GETGROUPS_T *gids = out_gids;-
381 GETGROUPS_T *in_gids = NULL;-
382 if (groups && *groups)
groupsDescription
TRUEnever evaluated
FALSEnever evaluated
*groupsDescription
TRUEnever evaluated
FALSEnever evaluated
0
383 {-
384 if (parse_additional_groups (groups, &in_gids, &n_gids, !n_gids) != 0)
parse_addition... !n_gids) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
385 {-
386 if (! n_gids)
! n_gidsDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 return EXIT_CANCELED;
never executed: return EXIT_CANCELED;
0
388 /* else look-up outside the chroot worked, then go with those. */-
389 }
never executed: end of block
0
390 else-
391 gids = in_gids;
never executed: gids = in_gids;
0
392 }-
393#if HAVE_SETGROUPS-
394 else if (! groups && gid_set (gid) && username)
! groupsDescription
TRUEnever evaluated
FALSEnever evaluated
(!gid_unset (gid))Description
TRUEnever evaluated
FALSEnever evaluated
usernameDescription
TRUEnever evaluated
FALSEnever evaluated
0
395 {-
396 int ngroups = xgetgroups (username, gid, &in_gids);-
397 if (ngroups <= 0)
ngroups <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
398 {-
399 if (! n_gids)
! n_gidsDescription
TRUEnever evaluated
FALSEnever evaluated
0
400 die (EXIT_CANCELED, errno,
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"failed to get supplemental groups\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((erro...d to get supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "failed to get supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
401 _("failed to get supplemental groups"));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"failed to get supplemental groups\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((erro...d to get supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "failed to get supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
402 /* else look-up outside the chroot worked, then go with those. */-
403 }
never executed: end of block
0
404 else-
405 {-
406 n_gids = ngroups;-
407 gids = in_gids;-
408 }
never executed: end of block
0
409 }-
410#endif-
411-
412 if ((uid_set (uid) || groups) && setgroups (n_gids, gids) != 0)
(!uid_unset (uid))Description
TRUEnever evaluated
FALSEnever evaluated
groupsDescription
TRUEnever evaluated
FALSEnever evaluated
setgroups (n_gids, gids) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
413 die (EXIT_CANCELED, errno, _("failed to set supplemental groups"));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"failed to set supplemental groups\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((erro...ed to set supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "failed to set supplemental groups" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
414-
415 free (in_gids);-
416 free (out_gids);-
417-
418 if (gid_set (gid) && setgid (gid))
(!gid_unset (gid))Description
TRUEnever evaluated
FALSEnever evaluated
setgid (gid)Description
TRUEnever evaluated
FALSEnever evaluated
0
419 die (EXIT_CANCELED, errno, _("failed to set group-ID"));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"failed to set group-ID\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error (EXIT_CAN...xt (((void *)0), "failed to set group-ID" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "failed to set group-ID" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
420-
421 if (uid_set (uid) && setuid (uid))
(!uid_unset (uid))Description
TRUEnever evaluated
FALSEnever evaluated
setuid (uid)Description
TRUEnever evaluated
FALSEnever evaluated
0
422 die (EXIT_CANCELED, errno, _("failed to set user-ID"));
never executed: ((!!sizeof (struct { _Static_assert (EXIT_CANCELED, "verify_expr (" "EXIT_CANCELED" ", " "(error (EXIT_CANCELED, (*__errno_location ()), dcgettext (((void *)0), \"failed to set user-ID\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error (EXIT_CANC...text (((void *)0), "failed to set user-ID" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error (EXIT_CANCELED, (*__errno_location ()) , dcgettext (((void *)0), "failed to set user-ID" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
423-
424 /* Execute the given command. */-
425 execvp (argv[0], argv);-
426-
427 int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
(*__errno_location ()) == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
428 error (0, errno, _("failed to run command %s"), quote (argv[0]));-
429 return exit_status;
never executed: return exit_status;
0
430}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2