2 * setpriv(1) - set various kernel privilege bits and run something
4 * Copyright (C) 2012 Andy Lutomirski <luto@amacapital.net>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <linux/securebits.h>
30 #include <sys/prctl.h>
31 #include <sys/types.h>
35 #include "closestream.h"
40 #include "pathnames.h"
42 #ifndef PR_SET_NO_NEW_PRIVS
43 # define PR_SET_NO_NEW_PRIVS 38
45 #ifndef PR_GET_NO_NEW_PRIVS
46 # define PR_GET_NO_NEW_PRIVS 39
49 #define SETPRIV_EXIT_PRIVERR 127 /* how we exit when we fail to set privs */
52 * Note: We are subject to https://bugzilla.redhat.com/show_bug.cgi?id=895105
53 * and we will therefore have problems if new capabilities are added. Once
54 * that bug is fixed, I'll (Andy Lutomirski) submit a corresponding fix to
55 * setpriv. In the mean time, the code here tries to work reasonably well.
60 nnp
:1, /* no_new_privs */
61 have_ruid
:1, /* real uid */
62 have_euid
:1, /* effective uid */
63 have_rgid
:1, /* real gid */
64 have_egid
:1, /* effective gid */
65 have_passwd
:1, /* passwd entry */
66 have_groups
:1, /* add groups */
67 keep_groups
:1, /* keep groups */
68 clear_groups
:1, /* remove groups */
69 init_groups
:1, /* initialize groups */
70 have_securebits
:1; /* remove groups */
76 /* real user passwd entry */
79 /* supplementary groups */
84 const char *caps_to_inherit
;
85 const char *bounding_set
;
91 const char *selinux_label
;
92 const char *apparmor_profile
;
95 static void __attribute__((__noreturn__
)) usage(void)
98 fputs(USAGE_HEADER
, out
);
99 fprintf(out
, _(" %s [options] <program> [<argument>...]\n"),
100 program_invocation_short_name
);
102 fputs(USAGE_SEPARATOR
, out
);
103 fputs(_("Run a program with different privilege settings.\n"), out
);
105 fputs(USAGE_OPTIONS
, out
);
106 fputs(_(" -d, --dump show current state (and do not exec anything)\n"), out
);
107 fputs(_(" --nnp, --no-new-privs disallow granting new privileges\n"), out
);
108 fputs(_(" --inh-caps <caps,...> set inheritable capabilities\n"), out
);
109 fputs(_(" --bounding-set <caps> set capability bounding set\n"), out
);
110 fputs(_(" --ruid <uid> set real uid\n"), out
);
111 fputs(_(" --euid <uid> set effective uid\n"), out
);
112 fputs(_(" --rgid <gid> set real gid\n"), out
);
113 fputs(_(" --egid <gid> set effective gid\n"), out
);
114 fputs(_(" --reuid <uid> set real and effective uid\n"), out
);
115 fputs(_(" --regid <gid> set real and effective gid\n"), out
);
116 fputs(_(" --clear-groups clear supplementary groups\n"), out
);
117 fputs(_(" --keep-groups keep supplementary groups\n"), out
);
118 fputs(_(" --init-groups initialize supplementary groups\n"), out
);
119 fputs(_(" --groups <group,...> set supplementary groups\n"), out
);
120 fputs(_(" --securebits <bits> set securebits\n"), out
);
121 fputs(_(" --selinux-label <label> set SELinux label\n"), out
);
122 fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out
);
124 fputs(USAGE_SEPARATOR
, out
);
125 fputs(USAGE_HELP
, out
);
126 fputs(USAGE_VERSION
, out
);
127 fputs(USAGE_SEPARATOR
, out
);
128 fputs(_(" This tool can be dangerous. Read the manpage, and be careful.\n"), out
);
129 fprintf(out
, USAGE_MAN_TAIL("setpriv(1)"));
134 static int real_cap_last_cap(void)
136 /* CAP_LAST_CAP is untrustworthy. */
144 f
= fopen(_PATH_PROC_CAPLASTCAP
, "r");
146 ret
= CAP_LAST_CAP
; /* guess */
150 matched
= fscanf(f
, "%d", &ret
);
154 ret
= CAP_LAST_CAP
; /* guess */
159 /* Returns the number of capabilities printed. */
160 static int print_caps(FILE *f
, capng_type_t which
)
162 int i
, n
= 0, max
= real_cap_last_cap();
164 for (i
= 0; i
<= max
; i
++) {
165 if (capng_have_capability(which
, i
)) {
166 const char *name
= capng_capability_to_name(i
);
172 /* cap-ng has very poor handling of
173 * CAP_LAST_CAP changes. This is the
182 static void dump_one_secbit(int *first
, int *bits
, int bit
, const char *name
)
194 static void dump_securebits(void)
197 int bits
= prctl(PR_GET_SECUREBITS
, 0, 0, 0, 0);
200 warnx(_("getting process secure bits failed"));
204 printf(_("Securebits: "));
206 dump_one_secbit(&first
, &bits
, SECBIT_NOROOT
, "noroot");
207 dump_one_secbit(&first
, &bits
, SECBIT_NOROOT_LOCKED
, "noroot_locked");
208 dump_one_secbit(&first
, &bits
, SECBIT_NO_SETUID_FIXUP
,
210 dump_one_secbit(&first
, &bits
, SECBIT_NO_SETUID_FIXUP_LOCKED
,
211 "no_setuid_fixup_locked");
212 bits
&= ~SECBIT_KEEP_CAPS
;
213 dump_one_secbit(&first
, &bits
, SECBIT_KEEP_CAPS_LOCKED
,
220 printf("0x%x", (unsigned)bits
);
224 printf(_("[none]\n"));
229 static void dump_label(const char *name
)
235 fd
= open(_PATH_PROC_ATTR_CURRENT
, O_RDONLY
);
237 warn(_("cannot open %s"), _PATH_PROC_ATTR_CURRENT
);
241 len
= read(fd
, buf
, sizeof(buf
));
246 warn(_("cannot read %s"), name
);
249 if (sizeof(buf
) - 1 <= (size_t)len
) {
250 warnx(_("%s: too long"), name
);
255 if (0 < len
&& buf
[len
- 1] == '\n')
257 printf("%s: %s\n", name
, buf
);
260 static void dump_groups(void)
262 int n
= getgroups(0, NULL
);
266 warn("getgroups failed");
270 groups
= xmalloc(n
* sizeof(gid_t
));
271 n
= getgroups(n
, groups
);
274 warn("getgroups failed");
278 printf(_("Supplementary groups: "));
283 for (i
= 0; i
< n
; i
++) {
286 printf("%ld", (long)groups
[i
]);
293 static void dump(int dumplevel
)
299 if (getresuid(&ru
, &eu
, &su
) == 0) {
300 printf(_("uid: %u\n"), ru
);
301 printf(_("euid: %u\n"), eu
);
302 /* Saved and fs uids always equal euid. */
304 printf(_("suid: %u\n"), su
);
306 warn(_("getresuid failed"));
308 if (getresgid(&rg
, &eg
, &sg
) == 0) {
309 printf("gid: %ld\n", (long)rg
);
310 printf("egid: %ld\n", (long)eg
);
311 /* Saved and fs gids always equal egid. */
313 printf("sgid: %ld\n", (long)sg
);
315 warn(_("getresgid failed"));
319 x
= prctl(PR_GET_NO_NEW_PRIVS
, 0, 0, 0, 0);
321 printf("no_new_privs: %d\n", x
);
323 warn("setting no_new_privs failed");
325 if (2 <= dumplevel
) {
326 printf(_("Effective capabilities: "));
327 if (print_caps(stdout
, CAPNG_EFFECTIVE
) == 0)
331 printf(_("Permitted capabilities: "));
332 if (print_caps(stdout
, CAPNG_PERMITTED
) == 0)
337 printf(_("Inheritable capabilities: "));
338 if (print_caps(stdout
, CAPNG_INHERITABLE
) == 0)
342 printf(_("Capability bounding set: "));
343 if (print_caps(stdout
, CAPNG_BOUNDING_SET
) == 0)
349 if (access(_PATH_SYS_SELINUX
, F_OK
) == 0)
350 dump_label(_("SELinux label"));
352 if (access(_PATH_SYS_APPARMOR
, F_OK
) == 0) {
353 dump_label(_("AppArmor profile"));
357 static void list_known_caps(void)
359 int i
, max
= real_cap_last_cap();
361 for (i
= 0; i
<= max
; i
++) {
362 const char *name
= capng_capability_to_name(i
);
364 printf("%s\n", name
);
366 warnx(_("cap %d: libcap-ng is broken"), i
);
370 static void parse_groups(struct privctx
*opts
, const char *str
)
372 char *groups
= xstrdup(str
);
373 char *buf
= groups
; /* We'll reuse it */
377 opts
->have_groups
= 1;
378 opts
->num_groups
= 0;
379 while ((c
= strsep(&groups
, ",")))
383 strcpy(buf
, str
); /* It's exactly the right length */
386 opts
->groups
= xcalloc(opts
->num_groups
, sizeof(gid_t
));
387 while ((c
= strsep(&groups
, ",")))
388 opts
->groups
[i
++] = (gid_t
) strtol_or_err(c
,
389 _("Invalid supplementary group id"));
394 static void do_setresuid(const struct privctx
*opts
)
396 uid_t ruid
, euid
, suid
;
397 if (getresuid(&ruid
, &euid
, &suid
) != 0)
398 err(SETPRIV_EXIT_PRIVERR
, _("getresuid failed"));
404 /* Also copy effective to saved (for paranoia). */
405 if (setresuid(ruid
, euid
, euid
) != 0)
406 err(SETPRIV_EXIT_PRIVERR
, _("setresuid failed"));
409 static void do_setresgid(const struct privctx
*opts
)
411 gid_t rgid
, egid
, sgid
;
412 if (getresgid(&rgid
, &egid
, &sgid
) != 0)
413 err(SETPRIV_EXIT_PRIVERR
, _("getresgid failed"));
419 /* Also copy effective to saved (for paranoia). */
420 if (setresgid(rgid
, egid
, egid
) != 0)
421 err(SETPRIV_EXIT_PRIVERR
, _("setresgid failed"));
424 static void bump_cap(unsigned int cap
)
426 if (capng_have_capability(CAPNG_PERMITTED
, cap
))
427 capng_update(CAPNG_ADD
, CAPNG_EFFECTIVE
, cap
);
430 static void do_caps(capng_type_t type
, const char *caps
)
432 char *my_caps
= xstrdup(caps
);
435 while ((c
= strsep(&my_caps
, ","))) {
442 errx(EXIT_FAILURE
, _("bad capability string"));
444 if (!strcmp(c
+ 1, "all")) {
446 /* It would be really bad if -all didn't drop all
447 * caps. It's better to just fail. */
448 if (real_cap_last_cap() > CAP_LAST_CAP
)
449 errx(SETPRIV_EXIT_PRIVERR
,
450 _("libcap-ng is too old for \"all\" caps"));
451 for (i
= 0; i
<= CAP_LAST_CAP
; i
++)
452 capng_update(action
, type
, i
);
454 int cap
= capng_name_to_capability(c
+ 1);
456 capng_update(action
, type
, cap
);
459 _("unknown capability \"%s\""), c
+ 1);
466 static void parse_securebits(struct privctx
*opts
, const char *arg
)
468 char *buf
= xstrdup(arg
);
471 opts
->have_securebits
= 1;
472 opts
->securebits
= prctl(PR_GET_SECUREBITS
, 0, 0, 0, 0);
473 if (opts
->securebits
< 0)
474 err(SETPRIV_EXIT_PRIVERR
, _("getting process secure bits failed"));
476 if (opts
->securebits
& ~(int)(SECBIT_NOROOT
|
477 SECBIT_NOROOT_LOCKED
|
478 SECBIT_NO_SETUID_FIXUP
|
479 SECBIT_NO_SETUID_FIXUP_LOCKED
|
481 SECBIT_KEEP_CAPS_LOCKED
))
482 errx(SETPRIV_EXIT_PRIVERR
,
483 _("unrecognized securebit set -- refusing to adjust"));
485 while ((c
= strsep(&buf
, ","))) {
486 if (*c
!= '+' && *c
!= '-')
487 errx(EXIT_FAILURE
, _("bad securebits string"));
489 if (!strcmp(c
+ 1, "all")) {
491 opts
->securebits
= 0;
494 _("+all securebits is not allowed"));
497 if (!strcmp(c
+ 1, "noroot"))
499 else if (!strcmp(c
+ 1, "noroot_locked"))
500 bit
= SECBIT_NOROOT_LOCKED
;
501 else if (!strcmp(c
+ 1, "no_setuid_fixup"))
502 bit
= SECBIT_NO_SETUID_FIXUP
;
503 else if (!strcmp(c
+ 1, "no_setuid_fixup_locked"))
504 bit
= SECBIT_NO_SETUID_FIXUP_LOCKED
;
505 else if (!strcmp(c
+ 1, "keep_caps"))
507 _("adjusting keep_caps does not make sense"));
508 else if (!strcmp(c
+ 1, "keep_caps_locked"))
509 bit
= SECBIT_KEEP_CAPS_LOCKED
; /* sigh */
511 errx(EXIT_FAILURE
, _("unrecognized securebit"));
514 opts
->securebits
|= bit
;
516 opts
->securebits
&= ~bit
;
520 opts
->securebits
|= SECBIT_KEEP_CAPS
; /* We need it, and it's reset on exec */
525 static void do_selinux_label(const char *label
)
530 if (access(_PATH_SYS_SELINUX
, F_OK
) != 0)
531 errx(SETPRIV_EXIT_PRIVERR
, _("SELinux is not running"));
533 fd
= open(_PATH_PROC_ATTR_EXEC
, O_RDWR
);
535 err(SETPRIV_EXIT_PRIVERR
,
536 _("cannot open %s"), _PATH_PROC_ATTR_EXEC
);
540 if (write(fd
, label
, len
) != (ssize_t
) len
)
541 err(SETPRIV_EXIT_PRIVERR
,
542 _("write failed: %s"), _PATH_PROC_ATTR_EXEC
);
545 err(SETPRIV_EXIT_PRIVERR
,
546 _("close failed: %s"), _PATH_PROC_ATTR_EXEC
);
549 static void do_apparmor_profile(const char *label
)
553 if (access(_PATH_SYS_APPARMOR
, F_OK
) != 0)
554 errx(SETPRIV_EXIT_PRIVERR
, _("AppArmor is not running"));
556 f
= fopen(_PATH_PROC_ATTR_EXEC
, "r+");
558 err(SETPRIV_EXIT_PRIVERR
,
559 _("cannot open %s"), _PATH_PROC_ATTR_EXEC
);
561 fprintf(f
, "exec %s", label
);
563 if (close_stream(f
) != 0)
564 err(SETPRIV_EXIT_PRIVERR
,
565 _("write failed: %s"), _PATH_PROC_ATTR_EXEC
);
568 static uid_t
get_user(const char *s
, const char *err
)
575 tmp
= strtol_or_err(s
, err
);
579 static gid_t
get_group(const char *s
, const char *err
)
586 tmp
= strtol_or_err(s
, err
);
590 static struct passwd
*get_passwd(const char *s
, uid_t
*uid
, const char *err
)
598 tmp
= strtol_or_err(s
, err
);
605 static struct passwd
*passwd_copy(struct passwd
*dst
, const struct passwd
*src
)
608 rv
= memcpy(dst
, src
, sizeof(*dst
));
609 rv
->pw_name
= xstrdup(rv
->pw_name
);
610 rv
->pw_passwd
= xstrdup(rv
->pw_passwd
);
611 rv
->pw_gecos
= xstrdup(rv
->pw_gecos
);
612 rv
->pw_dir
= xstrdup(rv
->pw_dir
);
613 rv
->pw_shell
= xstrdup(rv
->pw_shell
);
617 int main(int argc
, char **argv
)
639 static const struct option longopts
[] = {
640 { "dump", no_argument
, NULL
, 'd' },
641 { "nnp", no_argument
, NULL
, NNP
},
642 { "no-new-privs", no_argument
, NULL
, NNP
},
643 { "inh-caps", required_argument
, NULL
, INHCAPS
},
644 { "list-caps", no_argument
, NULL
, LISTCAPS
},
645 { "ruid", required_argument
, NULL
, RUID
},
646 { "euid", required_argument
, NULL
, EUID
},
647 { "rgid", required_argument
, NULL
, RGID
},
648 { "egid", required_argument
, NULL
, EGID
},
649 { "reuid", required_argument
, NULL
, REUID
},
650 { "regid", required_argument
, NULL
, REGID
},
651 { "clear-groups", no_argument
, NULL
, CLEAR_GROUPS
},
652 { "keep-groups", no_argument
, NULL
, KEEP_GROUPS
},
653 { "init-groups", no_argument
, NULL
, INIT_GROUPS
},
654 { "groups", required_argument
, NULL
, GROUPS
},
655 { "bounding-set", required_argument
, NULL
, CAPBSET
},
656 { "securebits", required_argument
, NULL
, SECUREBITS
},
657 { "selinux-label", required_argument
, NULL
, SELINUX_LABEL
},
658 { "apparmor-profile", required_argument
, NULL
, APPARMOR_PROFILE
},
659 { "help", no_argument
, NULL
, 'h' },
660 { "version", no_argument
, NULL
, 'V' },
664 static const ul_excl_t excl
[] = {
665 /* keep in same order with enum definitions */
666 {CLEAR_GROUPS
, KEEP_GROUPS
, INIT_GROUPS
, GROUPS
},
669 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
673 struct passwd
*pw
= NULL
;
678 setlocale(LC_ALL
, "");
679 bindtextdomain(PACKAGE
, LOCALEDIR
);
681 atexit(close_stdout
);
683 memset(&opts
, 0, sizeof(opts
));
685 while ((c
= getopt_long(argc
, argv
, "+dhV", longopts
, NULL
)) != -1) {
686 err_exclusive_options(c
, longopts
, excl
, excl_st
);
695 _("duplicate --no-new-privs option"));
700 errx(EXIT_FAILURE
, _("duplicate ruid"));
702 pw
= get_passwd(optarg
, &opts
.ruid
, _("failed to parse ruid"));
704 passwd_copy(&opts
.passwd
, pw
);
705 opts
.have_passwd
= 1;
710 errx(EXIT_FAILURE
, _("duplicate euid"));
712 opts
.euid
= get_user(optarg
, _("failed to parse euid"));
715 if (opts
.have_ruid
|| opts
.have_euid
)
716 errx(EXIT_FAILURE
, _("duplicate ruid or euid"));
717 opts
.have_ruid
= opts
.have_euid
= 1;
718 pw
= get_passwd(optarg
, &opts
.ruid
, _("failed to parse reuid"));
719 opts
.euid
= opts
.ruid
;
721 passwd_copy(&opts
.passwd
, pw
);
722 opts
.have_passwd
= 1;
727 errx(EXIT_FAILURE
, _("duplicate rgid"));
729 opts
.rgid
= get_group(optarg
, _("failed to parse rgid"));
733 errx(EXIT_FAILURE
, _("duplicate egid"));
735 opts
.egid
= get_group(optarg
, _("failed to parse egid"));
738 if (opts
.have_rgid
|| opts
.have_egid
)
739 errx(EXIT_FAILURE
, _("duplicate rgid or egid"));
740 opts
.have_rgid
= opts
.have_egid
= 1;
741 opts
.rgid
= opts
.egid
= get_group(optarg
, _("failed to parse regid"));
744 if (opts
.clear_groups
)
746 _("duplicate --clear-groups option"));
747 opts
.clear_groups
= 1;
750 if (opts
.keep_groups
)
752 _("duplicate --keep-groups option"));
753 opts
.keep_groups
= 1;
756 if (opts
.init_groups
)
758 _("duplicate --init-groups option"));
759 opts
.init_groups
= 1;
762 if (opts
.have_groups
)
764 _("duplicate --groups option"));
765 parse_groups(&opts
, optarg
);
771 if (opts
.caps_to_inherit
)
773 _("duplicate --inh-caps option"));
774 opts
.caps_to_inherit
= optarg
;
777 if (opts
.bounding_set
)
779 _("duplicate --bounding-set option"));
780 opts
.bounding_set
= optarg
;
783 if (opts
.have_securebits
)
785 _("duplicate --securebits option"));
786 parse_securebits(&opts
, optarg
);
789 if (opts
.selinux_label
)
791 _("duplicate --selinux-label option"));
792 opts
.selinux_label
= optarg
;
794 case APPARMOR_PROFILE
:
795 if (opts
.apparmor_profile
)
797 _("duplicate --apparmor-profile option"));
798 opts
.apparmor_profile
= optarg
;
803 printf(UTIL_LINUX_VERSION
);
806 errtryhelp(EXIT_FAILURE
);
811 if (total_opts
!= dumplevel
|| optind
< argc
)
813 _("--dump is incompatible with all other options"));
819 if (total_opts
!= 1 || optind
< argc
)
821 _("--list-caps must be specified alone"));
827 errx(EXIT_FAILURE
, _("No program specified"));
829 if ((opts
.have_rgid
|| opts
.have_egid
)
830 && !opts
.keep_groups
&& !opts
.clear_groups
&& !opts
.init_groups
831 && !opts
.have_groups
)
833 _("--[re]gid requires --keep-groups, --clear-groups, --init-groups, or --groups"));
835 if (opts
.init_groups
&& !opts
.have_ruid
)
837 _("--init-groups requires --ruid or --reuid"));
839 if (opts
.init_groups
&& !opts
.have_passwd
)
841 _("uid %ld not found, --init-groups requires an user that "
842 "can be found on the system"),
845 if (opts
.nnp
&& prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) == -1)
846 err(EXIT_FAILURE
, _("disallow granting new privileges failed"));
848 if (opts
.selinux_label
)
849 do_selinux_label(opts
.selinux_label
);
850 if (opts
.apparmor_profile
)
851 do_apparmor_profile(opts
.apparmor_profile
);
853 if (prctl(PR_SET_KEEPCAPS
, 1, 0, 0, 0) == -1)
854 err(EXIT_FAILURE
, _("keep process capabilities failed"));
856 /* We're going to want CAP_SETPCAP, CAP_SETUID, and CAP_SETGID if
858 bump_cap(CAP_SETPCAP
);
859 bump_cap(CAP_SETUID
);
860 bump_cap(CAP_SETGID
);
861 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
862 err(SETPRIV_EXIT_PRIVERR
, _("activate capabilities"));
864 if (opts
.have_ruid
|| opts
.have_euid
) {
866 /* KEEPCAPS doesn't work for the effective mask. */
867 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
868 err(SETPRIV_EXIT_PRIVERR
, _("reactivate capabilities"));
871 if (opts
.have_rgid
|| opts
.have_egid
)
874 if (opts
.have_groups
) {
875 if (setgroups(opts
.num_groups
, opts
.groups
) != 0)
876 err(SETPRIV_EXIT_PRIVERR
, _("setgroups failed"));
877 } else if (opts
.init_groups
) {
878 if (initgroups(opts
.passwd
.pw_name
, opts
.passwd
.pw_gid
) != 0)
879 err(SETPRIV_EXIT_PRIVERR
, _("initgroups failed"));
880 } else if (opts
.clear_groups
) {
882 if (setgroups(0, &x
) != 0)
883 err(SETPRIV_EXIT_PRIVERR
, _("setgroups failed"));
886 if (opts
.have_securebits
&& prctl(PR_SET_SECUREBITS
, opts
.securebits
, 0, 0, 0) != 0)
887 err(SETPRIV_EXIT_PRIVERR
, _("set process securebits failed"));
889 if (opts
.bounding_set
) {
890 do_caps(CAPNG_BOUNDING_SET
, opts
.bounding_set
);
891 errno
= EPERM
; /* capng doesn't set errno if we're missing CAP_SETPCAP */
892 if (capng_apply(CAPNG_SELECT_BOUNDS
) != 0)
893 err(SETPRIV_EXIT_PRIVERR
, _("apply bounding set"));
896 if (opts
.caps_to_inherit
) {
897 do_caps(CAPNG_INHERITABLE
, opts
.caps_to_inherit
);
898 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
899 err(SETPRIV_EXIT_PRIVERR
, _("apply capabilities"));
902 execvp(argv
[optind
], argv
+ optind
);
904 err(EXIT_FAILURE
, _("cannot execute: %s"), argv
[optind
]);