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>
37 #include "closestream.h"
42 #include "pathnames.h"
45 #include "setpriv-landlock.h"
48 #ifndef PR_SET_NO_NEW_PRIVS
49 # define PR_SET_NO_NEW_PRIVS 38
51 #ifndef PR_GET_NO_NEW_PRIVS
52 # define PR_GET_NO_NEW_PRIVS 39
55 #define SETPRIV_EXIT_PRIVERR 127 /* how we exit when we fail to set privs */
57 /* The shell to set SHELL env.variable if none is given in the user's passwd entry. */
58 #define DEFAULT_SHELL "/bin/sh"
60 static gid_t
get_group(const char *s
, const char *err
);
63 CAP_TYPE_EFFECTIVE
= CAPNG_EFFECTIVE
,
64 CAP_TYPE_PERMITTED
= CAPNG_PERMITTED
,
65 CAP_TYPE_INHERITABLE
= CAPNG_INHERITABLE
,
66 CAP_TYPE_BOUNDING
= CAPNG_BOUNDING_SET
,
67 CAP_TYPE_AMBIENT
= (1 << 4)
71 * Note: We are subject to https://bugzilla.redhat.com/show_bug.cgi?id=895105
72 * and we will therefore have problems if new capabilities are added. Once
73 * that bug is fixed, I'll (Andy Lutomirski) submit a corresponding fix to
74 * setpriv. In the mean time, the code here tries to work reasonably well.
79 nnp
:1, /* no_new_privs */
80 have_ruid
:1, /* real uid */
81 have_euid
:1, /* effective uid */
82 have_rgid
:1, /* real gid */
83 have_egid
:1, /* effective gid */
84 have_passwd
:1, /* passwd entry */
85 have_groups
:1, /* add groups */
86 keep_groups
:1, /* keep groups */
87 clear_groups
:1, /* remove groups */
88 init_groups
:1, /* initialize groups */
89 reset_env
:1, /* reset environment */
90 have_securebits
:1; /* remove groups */
96 /* real user passwd entry */
99 /* supplementary groups */
104 const char *caps_to_inherit
;
105 const char *ambient_caps
;
106 const char *bounding_set
;
110 /* parent death signal (<0 clear, 0 nothing, >0 signal) */
114 const char *selinux_label
;
115 const char *apparmor_profile
;
116 struct setpriv_landlock_opts landlock
;
117 const char *seccomp_filter
;
120 static void __attribute__((__noreturn__
)) usage(void)
123 fputs(USAGE_HEADER
, out
);
124 fprintf(out
, _(" %s [options] <program> [<argument>...]\n"),
125 program_invocation_short_name
);
127 fputs(USAGE_SEPARATOR
, out
);
128 fputs(_("Run a program with different privilege settings.\n"), out
);
130 fputs(USAGE_OPTIONS
, out
);
131 fputs(_(" -d, --dump show current state (and do not exec)\n"), out
);
132 fputs(_(" --nnp, --no-new-privs disallow granting new privileges\n"), out
);
133 fputs(_(" --ambient-caps <caps,...> set ambient capabilities\n"), out
);
134 fputs(_(" --inh-caps <caps,...> set inheritable capabilities\n"), out
);
135 fputs(_(" --bounding-set <caps> set capability bounding set\n"), out
);
136 fputs(_(" --ruid <uid|user> set real uid\n"), out
);
137 fputs(_(" --euid <uid|user> set effective uid\n"), out
);
138 fputs(_(" --rgid <gid|user> set real gid\n"), out
);
139 fputs(_(" --egid <gid|group> set effective gid\n"), out
);
140 fputs(_(" --reuid <uid|user> set real and effective uid\n"), out
);
141 fputs(_(" --regid <gid|group> set real and effective gid\n"), out
);
142 fputs(_(" --clear-groups clear supplementary groups\n"), out
);
143 fputs(_(" --keep-groups keep supplementary groups\n"), out
);
144 fputs(_(" --init-groups initialize supplementary groups\n"), out
);
145 fputs(_(" --groups <group,...> set supplementary groups by UID or name\n"), out
);
146 fputs(_(" --securebits <bits> set securebits\n"), out
);
147 fputs(_(" --pdeathsig keep|clear|<signame>\n"
148 " set or clear parent death signal\n"), out
);
149 fputs(_(" --selinux-label <label> set SELinux label\n"), out
);
150 fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out
);
151 fputs(_(" --landlock-access <access> add Landlock access\n"), out
);
152 fputs(_(" --landlock-rule <rule> add Landlock rule\n"), out
);
153 fputs(_(" --seccomp-filter <file> load seccomp filter from file\n"), out
);
154 fputs(_(" --reset-env clear all environment and initialize\n"
155 " HOME, SHELL, USER, LOGNAME and PATH\n"), out
);
157 fputs(USAGE_SEPARATOR
, out
);
158 fprintf(out
, USAGE_HELP_OPTIONS(29));
159 fputs(USAGE_SEPARATOR
, out
);
160 fputs(_(" This tool can be dangerous. Read the manpage, and be careful.\n"), out
);
161 fprintf(out
, USAGE_MAN_TAIL("setpriv(1)"));
168 static int has_cap(enum cap_type which
, unsigned int i
)
171 case CAP_TYPE_EFFECTIVE
:
172 case CAP_TYPE_BOUNDING
:
173 case CAP_TYPE_INHERITABLE
:
174 case CAP_TYPE_PERMITTED
:
175 return capng_have_capability((capng_type_t
)which
, i
);
176 case CAP_TYPE_AMBIENT
:
177 return prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_IS_SET
,
178 (unsigned long) i
, 0UL, 0UL);
180 warnx(_("invalid capability type"));
185 /* Returns the number of capabilities printed. */
186 static int print_caps(FILE *f
, enum cap_type which
)
188 int i
, n
= 0, max
= cap_last_cap();
190 for (i
= 0; i
<= max
; i
++) {
191 int ret
= has_cap(which
, i
);
193 if (i
== 0 && ret
< 0)
197 const char *name
= capng_capability_to_name(i
);
203 warnx(_("cap %d: libcap-ng is broken"), i
);
211 static void dump_one_secbit(int *first
, int *bits
, int bit
, const char *name
)
223 static void dump_securebits(void)
226 int bits
= prctl(PR_GET_SECUREBITS
, 0, 0, 0, 0);
229 warnx(_("getting process secure bits failed"));
233 printf(_("Securebits: "));
235 dump_one_secbit(&first
, &bits
, SECBIT_NOROOT
, "noroot");
236 dump_one_secbit(&first
, &bits
, SECBIT_NOROOT_LOCKED
, "noroot_locked");
237 dump_one_secbit(&first
, &bits
, SECBIT_NO_SETUID_FIXUP
,
239 dump_one_secbit(&first
, &bits
, SECBIT_NO_SETUID_FIXUP_LOCKED
,
240 "no_setuid_fixup_locked");
241 bits
&= ~SECBIT_KEEP_CAPS
;
242 dump_one_secbit(&first
, &bits
, SECBIT_KEEP_CAPS_LOCKED
,
249 printf("0x%x", (unsigned)bits
);
253 printf(_("[none]\n"));
258 static void dump_label(const char *name
)
264 fd
= open(_PATH_PROC_ATTR_CURRENT
, O_RDONLY
);
266 warn(_("cannot open %s"), _PATH_PROC_ATTR_CURRENT
);
270 len
= read(fd
, buf
, sizeof(buf
));
275 warn(_("cannot read %s"), name
);
278 if (sizeof(buf
) - 1 <= (size_t)len
) {
279 warnx(_("%s: too long"), name
);
284 if (0 < len
&& buf
[len
- 1] == '\n')
286 printf("%s: %s\n", name
, buf
);
289 static void dump_groups(void)
291 int n
= getgroups(0, NULL
);
295 warn("getgroups failed");
299 groups
= xmalloc(n
* sizeof(gid_t
));
300 n
= getgroups(n
, groups
);
303 warn("getgroups failed");
307 printf(_("Supplementary groups: "));
312 for (i
= 0; i
< n
; i
++) {
315 printf("%ld", (long)groups
[i
]);
322 static void dump_pdeathsig(void)
326 if (prctl(PR_GET_PDEATHSIG
, &pdeathsig
) != 0) {
327 warn(_("get pdeathsig failed"));
331 printf(_("Parent death signal: "));
332 if (pdeathsig
&& signum_to_signame(pdeathsig
) != NULL
)
333 printf("%s\n", signum_to_signame(pdeathsig
));
335 printf("%d\n", pdeathsig
);
337 printf(_("[none]\n"));
340 static void dump(int dumplevel
)
346 if (getresuid(&ru
, &eu
, &su
) == 0) {
347 printf(_("uid: %u\n"), ru
);
348 printf(_("euid: %u\n"), eu
);
349 /* Saved and fs uids always equal euid. */
351 printf(_("suid: %u\n"), su
);
353 warn(_("getresuid failed"));
355 if (getresgid(&rg
, &eg
, &sg
) == 0) {
356 printf("gid: %ld\n", (long)rg
);
357 printf("egid: %ld\n", (long)eg
);
358 /* Saved and fs gids always equal egid. */
360 printf("sgid: %ld\n", (long)sg
);
362 warn(_("getresgid failed"));
366 x
= prctl(PR_GET_NO_NEW_PRIVS
, 0, 0, 0, 0);
368 printf("no_new_privs: %d\n", x
);
370 warn("setting no_new_privs failed");
372 if (2 <= dumplevel
) {
373 printf(_("Effective capabilities: "));
374 if (print_caps(stdout
, CAP_TYPE_EFFECTIVE
) == 0)
378 printf(_("Permitted capabilities: "));
379 if (print_caps(stdout
, CAP_TYPE_PERMITTED
) == 0)
384 printf(_("Inheritable capabilities: "));
385 if (print_caps(stdout
, CAP_TYPE_INHERITABLE
) == 0)
389 printf(_("Ambient capabilities: "));
390 x
= print_caps(stdout
, CAP_TYPE_AMBIENT
);
394 printf(_("[unsupported]"));
397 printf(_("Capability bounding set: "));
398 if (print_caps(stdout
, CAP_TYPE_BOUNDING
) == 0)
405 if (access(_PATH_SYS_SELINUX
, F_OK
) == 0)
406 dump_label(_("SELinux label"));
408 if (access(_PATH_SYS_APPARMOR
, F_OK
) == 0) {
409 dump_label(_("AppArmor profile"));
413 static void list_known_caps(void)
415 int i
, max
= cap_last_cap();
417 for (i
= 0; i
<= max
; i
++) {
418 const char *name
= capng_capability_to_name(i
);
420 printf("%s\n", name
);
422 warnx(_("cap %d: libcap-ng is broken"), i
);
426 static void parse_groups(struct privctx
*opts
, const char *str
)
428 char *groups
= xstrdup(str
);
429 char *buf
= groups
; /* We'll reuse it */
433 opts
->have_groups
= 1;
434 opts
->num_groups
= 0;
435 while ((c
= strsep(&groups
, ",")))
439 strcpy(buf
, str
); /* It's exactly the right length */
442 opts
->groups
= xcalloc(opts
->num_groups
, sizeof(gid_t
));
443 while ((c
= strsep(&groups
, ",")))
444 opts
->groups
[i
++] = get_group(c
, _("Invalid supplementary group id"));
449 static void parse_pdeathsig(struct privctx
*opts
, const char *str
)
451 if (!strcmp(str
, "keep")) {
452 if (prctl(PR_GET_PDEATHSIG
, &opts
->pdeathsig
) != 0)
453 errx(SETPRIV_EXIT_PRIVERR
,
454 _("failed to get parent death signal"));
455 } else if (!strcmp(str
, "clear")) {
456 opts
->pdeathsig
= -1;
457 } else if ((opts
->pdeathsig
= signame_to_signum(str
)) < 0) {
458 errx(EXIT_FAILURE
, _("unknown signal: %s"), str
);
462 static void do_setresuid(const struct privctx
*opts
)
464 uid_t ruid
, euid
, suid
;
465 if (getresuid(&ruid
, &euid
, &suid
) != 0)
466 err(SETPRIV_EXIT_PRIVERR
, _("getresuid failed"));
472 /* Also copy effective to saved (for paranoia). */
473 if (setresuid(ruid
, euid
, euid
) != 0)
474 err(SETPRIV_EXIT_PRIVERR
, _("setresuid failed"));
477 static void do_setresgid(const struct privctx
*opts
)
479 gid_t rgid
, egid
, sgid
;
480 if (getresgid(&rgid
, &egid
, &sgid
) != 0)
481 err(SETPRIV_EXIT_PRIVERR
, _("getresgid failed"));
487 /* Also copy effective to saved (for paranoia). */
488 if (setresgid(rgid
, egid
, egid
) != 0)
489 err(SETPRIV_EXIT_PRIVERR
, _("setresgid failed"));
492 static void bump_cap(unsigned int cap
)
494 if (capng_have_capability(CAPNG_PERMITTED
, cap
))
495 capng_update(CAPNG_ADD
, CAPNG_EFFECTIVE
, cap
);
498 static int cap_update(capng_act_t action
,
499 enum cap_type type
, unsigned int cap
)
502 case CAP_TYPE_EFFECTIVE
:
503 case CAP_TYPE_BOUNDING
:
504 case CAP_TYPE_INHERITABLE
:
505 case CAP_TYPE_PERMITTED
:
506 return capng_update(action
, (capng_type_t
) type
, cap
);
507 case CAP_TYPE_AMBIENT
:
511 if (action
== CAPNG_ADD
)
512 ret
= prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_RAISE
,
513 (unsigned long) cap
, 0UL, 0UL);
515 ret
= prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_LOWER
,
516 (unsigned long) cap
, 0UL, 0UL);
521 errx(EXIT_FAILURE
, _("unsupported capability type"));
526 static void do_caps(enum cap_type type
, const char *caps
)
528 char *my_caps
= xstrdup(caps
);
531 while ((c
= strsep(&my_caps
, ","))) {
538 errx(EXIT_FAILURE
, _("bad capability string"));
540 if (!strcmp(c
+ 1, "all")) {
542 /* We can trust the return value from cap_last_cap(),
543 * so use that directly. */
544 for (i
= 0; i
<= cap_last_cap(); i
++)
545 cap_update(action
, type
, i
);
547 int cap
= capng_name_to_capability(c
+ 1);
549 cap_update(action
, type
, cap
);
550 else if (sscanf(c
+ 1, "cap_%d", &cap
) == 1
551 && 0 <= cap
&& cap
<= cap_last_cap())
552 cap_update(action
, type
, cap
);
555 _("unknown capability \"%s\""), c
+ 1);
562 static void parse_securebits(struct privctx
*opts
, const char *arg
)
564 char *buf
= xstrdup(arg
);
567 opts
->have_securebits
= 1;
568 opts
->securebits
= prctl(PR_GET_SECUREBITS
, 0, 0, 0, 0);
569 if (opts
->securebits
< 0)
570 err(SETPRIV_EXIT_PRIVERR
, _("getting process secure bits failed"));
572 if (opts
->securebits
& ~(int)(SECBIT_NOROOT
|
573 SECBIT_NOROOT_LOCKED
|
574 SECBIT_NO_SETUID_FIXUP
|
575 SECBIT_NO_SETUID_FIXUP_LOCKED
|
577 SECBIT_KEEP_CAPS_LOCKED
))
578 errx(SETPRIV_EXIT_PRIVERR
,
579 _("unrecognized securebit set -- refusing to adjust"));
581 while ((c
= strsep(&buf
, ","))) {
582 if (*c
!= '+' && *c
!= '-')
583 errx(EXIT_FAILURE
, _("bad securebits string"));
585 if (!strcmp(c
+ 1, "all")) {
587 opts
->securebits
= 0;
590 _("+all securebits is not allowed"));
593 if (!strcmp(c
+ 1, "noroot"))
595 else if (!strcmp(c
+ 1, "noroot_locked"))
596 bit
= SECBIT_NOROOT_LOCKED
;
597 else if (!strcmp(c
+ 1, "no_setuid_fixup"))
598 bit
= SECBIT_NO_SETUID_FIXUP
;
599 else if (!strcmp(c
+ 1, "no_setuid_fixup_locked"))
600 bit
= SECBIT_NO_SETUID_FIXUP_LOCKED
;
601 else if (!strcmp(c
+ 1, "keep_caps"))
603 _("adjusting keep_caps does not make sense"));
604 else if (!strcmp(c
+ 1, "keep_caps_locked"))
605 bit
= SECBIT_KEEP_CAPS_LOCKED
; /* sigh */
607 errx(EXIT_FAILURE
, _("unrecognized securebit"));
610 opts
->securebits
|= bit
;
612 opts
->securebits
&= ~bit
;
616 opts
->securebits
|= SECBIT_KEEP_CAPS
; /* We need it, and it's reset on exec */
621 static void do_selinux_label(const char *label
)
626 if (access(_PATH_SYS_SELINUX
, F_OK
) != 0)
627 errx(SETPRIV_EXIT_PRIVERR
, _("SELinux is not running"));
629 fd
= open(_PATH_PROC_ATTR_EXEC
, O_RDWR
);
631 err(SETPRIV_EXIT_PRIVERR
,
632 _("cannot open %s"), _PATH_PROC_ATTR_EXEC
);
636 if (write(fd
, label
, len
) != (ssize_t
) len
)
637 err(SETPRIV_EXIT_PRIVERR
,
638 _("write failed: %s"), _PATH_PROC_ATTR_EXEC
);
641 err(SETPRIV_EXIT_PRIVERR
,
642 _("close failed: %s"), _PATH_PROC_ATTR_EXEC
);
645 static void do_apparmor_profile(const char *label
)
649 if (access(_PATH_SYS_APPARMOR
, F_OK
) != 0)
650 errx(SETPRIV_EXIT_PRIVERR
, _("AppArmor is not running"));
652 f
= fopen(_PATH_PROC_ATTR_EXEC
, "r+");
654 err(SETPRIV_EXIT_PRIVERR
,
655 _("cannot open %s"), _PATH_PROC_ATTR_EXEC
);
657 fprintf(f
, "exec %s", label
);
659 if (close_stream(f
) != 0)
660 err(SETPRIV_EXIT_PRIVERR
,
661 _("write failed: %s"), _PATH_PROC_ATTR_EXEC
);
664 static void do_seccomp_filter(const char *file
)
669 struct sock_fprog prog
= {};
671 fd
= open(file
, O_RDONLY
);
673 err(SETPRIV_EXIT_PRIVERR
,
674 _("cannot open %s"), file
);
676 s
= read_all_alloc(fd
, &filter
);
678 err(SETPRIV_EXIT_PRIVERR
,
679 _("cannot read %s"), file
);
681 if (s
% sizeof(*prog
.filter
))
682 errx(SETPRIV_EXIT_PRIVERR
, _("invalid filter"));
684 prog
.len
= s
/ sizeof(*prog
.filter
);
685 prog
.filter
= (void *)filter
;
687 /* *SET* below will return EINVAL when either the filter is invalid or
688 * seccomp is not supported. To distinguish those cases do a *GET* here
690 if (prctl(PR_GET_SECCOMP
) == -1 && errno
== EINVAL
)
691 err(SETPRIV_EXIT_PRIVERR
, _("Seccomp non-functional"));
693 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0))
694 err(SETPRIV_EXIT_PRIVERR
, _("Could not run prctl(PR_SET_NO_NEW_PRIVS)"));
696 if (ul_set_seccomp_filter_spec_allow(&prog
))
697 err(SETPRIV_EXIT_PRIVERR
, _("Could not load seccomp filter"));
704 static void do_reset_environ(struct passwd
*pw
)
706 char *term
= getenv("TERM");
709 term
= xstrdup(term
);
716 xsetenv("TERM", term
, 1);
720 if (pw
->pw_shell
&& *pw
->pw_shell
)
721 xsetenv("SHELL", pw
->pw_shell
, 1);
723 xsetenv("SHELL", DEFAULT_SHELL
, 1);
725 xsetenv("HOME", pw
->pw_dir
, 1);
726 xsetenv("USER", pw
->pw_name
, 1);
727 xsetenv("LOGNAME", pw
->pw_name
, 1);
730 xsetenv("PATH", _PATH_DEFPATH
, 1);
732 xsetenv("PATH", _PATH_DEFPATH_ROOT
, 1);
735 static uid_t
get_user(const char *s
, const char *err
)
742 tmp
= strtol_or_err(s
, err
);
746 static gid_t
get_group(const char *s
, const char *err
)
753 tmp
= strtol_or_err(s
, err
);
757 static struct passwd
*get_passwd(const char *s
, uid_t
*uid
, const char *err
)
765 tmp
= strtol_or_err(s
, err
);
772 static struct passwd
*passwd_copy(struct passwd
*dst
, const struct passwd
*src
)
775 rv
= memcpy(dst
, src
, sizeof(*dst
));
776 rv
->pw_name
= xstrdup(rv
->pw_name
);
777 rv
->pw_passwd
= xstrdup(rv
->pw_passwd
);
778 rv
->pw_gecos
= xstrdup(rv
->pw_gecos
);
779 rv
->pw_dir
= xstrdup(rv
->pw_dir
);
780 rv
->pw_shell
= xstrdup(rv
->pw_shell
);
784 int main(int argc
, char **argv
)
812 static const struct option longopts
[] = {
813 { "dump", no_argument
, NULL
, 'd' },
814 { "nnp", no_argument
, NULL
, NNP
},
815 { "no-new-privs", no_argument
, NULL
, NNP
},
816 { "inh-caps", required_argument
, NULL
, INHCAPS
},
817 { "ambient-caps", required_argument
, NULL
, AMBCAPS
},
818 { "list-caps", no_argument
, NULL
, LISTCAPS
},
819 { "ruid", required_argument
, NULL
, RUID
},
820 { "euid", required_argument
, NULL
, EUID
},
821 { "rgid", required_argument
, NULL
, RGID
},
822 { "egid", required_argument
, NULL
, EGID
},
823 { "reuid", required_argument
, NULL
, REUID
},
824 { "regid", required_argument
, NULL
, REGID
},
825 { "clear-groups", no_argument
, NULL
, CLEAR_GROUPS
},
826 { "keep-groups", no_argument
, NULL
, KEEP_GROUPS
},
827 { "init-groups", no_argument
, NULL
, INIT_GROUPS
},
828 { "groups", required_argument
, NULL
, GROUPS
},
829 { "bounding-set", required_argument
, NULL
, CAPBSET
},
830 { "securebits", required_argument
, NULL
, SECUREBITS
},
831 { "pdeathsig", required_argument
, NULL
, PDEATHSIG
, },
832 { "selinux-label", required_argument
, NULL
, SELINUX_LABEL
},
833 { "apparmor-profile", required_argument
, NULL
, APPARMOR_PROFILE
},
834 { "landlock-access", required_argument
, NULL
, LANDLOCK_ACCESS
},
835 { "landlock-rule", required_argument
, NULL
, LANDLOCK_RULE
},
836 { "seccomp-filter", required_argument
, NULL
, SECCOMP_FILTER
},
837 { "help", no_argument
, NULL
, 'h' },
838 { "reset-env", no_argument
, NULL
, RESET_ENV
, },
839 { "version", no_argument
, NULL
, 'V' },
843 static const ul_excl_t excl
[] = {
844 /* keep in same order with enum definitions */
845 {CLEAR_GROUPS
, KEEP_GROUPS
, INIT_GROUPS
, GROUPS
},
848 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
852 struct passwd
*pw
= NULL
;
857 setlocale(LC_ALL
, "");
858 bindtextdomain(PACKAGE
, LOCALEDIR
);
860 close_stdout_atexit();
862 memset(&opts
, 0, sizeof(opts
));
863 init_landlock_opts(&opts
.landlock
);
865 while ((c
= getopt_long(argc
, argv
, "+dhV", longopts
, NULL
)) != -1) {
866 err_exclusive_options(c
, longopts
, excl
, excl_st
);
875 _("duplicate --no-new-privs option"));
880 errx(EXIT_FAILURE
, _("duplicate ruid"));
882 pw
= get_passwd(optarg
, &opts
.ruid
, _("failed to parse ruid"));
884 passwd_copy(&opts
.passwd
, pw
);
885 opts
.have_passwd
= 1;
890 errx(EXIT_FAILURE
, _("duplicate euid"));
892 opts
.euid
= get_user(optarg
, _("failed to parse euid"));
895 if (opts
.have_ruid
|| opts
.have_euid
)
896 errx(EXIT_FAILURE
, _("duplicate ruid or euid"));
897 opts
.have_ruid
= opts
.have_euid
= 1;
898 pw
= get_passwd(optarg
, &opts
.ruid
, _("failed to parse reuid"));
899 opts
.euid
= opts
.ruid
;
901 passwd_copy(&opts
.passwd
, pw
);
902 opts
.have_passwd
= 1;
907 errx(EXIT_FAILURE
, _("duplicate rgid"));
909 opts
.rgid
= get_group(optarg
, _("failed to parse rgid"));
913 errx(EXIT_FAILURE
, _("duplicate egid"));
915 opts
.egid
= get_group(optarg
, _("failed to parse egid"));
918 if (opts
.have_rgid
|| opts
.have_egid
)
919 errx(EXIT_FAILURE
, _("duplicate rgid or egid"));
920 opts
.have_rgid
= opts
.have_egid
= 1;
921 opts
.rgid
= opts
.egid
= get_group(optarg
, _("failed to parse regid"));
924 if (opts
.clear_groups
)
926 _("duplicate --clear-groups option"));
927 opts
.clear_groups
= 1;
930 if (opts
.keep_groups
)
932 _("duplicate --keep-groups option"));
933 opts
.keep_groups
= 1;
936 if (opts
.init_groups
)
938 _("duplicate --init-groups option"));
939 opts
.init_groups
= 1;
942 if (opts
.have_groups
)
944 _("duplicate --groups option"));
945 parse_groups(&opts
, optarg
);
950 _("duplicate --keep-pdeathsig option"));
951 parse_pdeathsig(&opts
, optarg
);
957 if (opts
.caps_to_inherit
)
959 _("duplicate --inh-caps option"));
960 opts
.caps_to_inherit
= optarg
;
963 if (opts
.ambient_caps
)
965 _("duplicate --ambient-caps option"));
966 opts
.ambient_caps
= optarg
;
969 if (opts
.bounding_set
)
971 _("duplicate --bounding-set option"));
972 opts
.bounding_set
= optarg
;
975 if (opts
.have_securebits
)
977 _("duplicate --securebits option"));
978 parse_securebits(&opts
, optarg
);
981 if (opts
.selinux_label
)
983 _("duplicate --selinux-label option"));
984 opts
.selinux_label
= optarg
;
986 case APPARMOR_PROFILE
:
987 if (opts
.apparmor_profile
)
989 _("duplicate --apparmor-profile option"));
990 opts
.apparmor_profile
= optarg
;
992 case LANDLOCK_ACCESS
:
993 parse_landlock_access(&opts
.landlock
, optarg
);
996 parse_landlock_rule(&opts
.landlock
, optarg
);
999 if (opts
.seccomp_filter
)
1001 _("duplicate --secccomp-filter option"));
1002 opts
.seccomp_filter
= optarg
;
1011 print_version(EXIT_SUCCESS
);
1013 errtryhelp(EXIT_FAILURE
);
1018 if (total_opts
!= dumplevel
|| optind
< argc
)
1020 _("--dump is incompatible with all other options"));
1022 return EXIT_SUCCESS
;
1026 if (total_opts
!= 1 || optind
< argc
)
1028 _("--list-caps must be specified alone"));
1030 return EXIT_SUCCESS
;
1034 errx(EXIT_FAILURE
, _("No program specified"));
1036 if ((opts
.have_rgid
|| opts
.have_egid
)
1037 && !opts
.keep_groups
&& !opts
.clear_groups
&& !opts
.init_groups
1038 && !opts
.have_groups
)
1040 _("--[re]gid requires --keep-groups, --clear-groups, --init-groups, or --groups"));
1042 if (opts
.init_groups
&& !opts
.have_ruid
)
1044 _("--init-groups requires --ruid or --reuid"));
1046 if (opts
.init_groups
&& !opts
.have_passwd
)
1048 _("uid %ld not found, --init-groups requires an user that "
1049 "can be found on the system"),
1052 if (opts
.reset_env
) {
1053 if (opts
.have_passwd
)
1054 /* pwd according to --ruid or --reuid */
1057 /* pwd for the current user */
1058 pw
= getpwuid(getuid());
1059 do_reset_environ(pw
);
1062 if (opts
.nnp
&& prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) == -1)
1063 err(EXIT_FAILURE
, _("disallow granting new privileges failed"));
1065 if (opts
.selinux_label
)
1066 do_selinux_label(opts
.selinux_label
);
1067 if (opts
.apparmor_profile
)
1068 do_apparmor_profile(opts
.apparmor_profile
);
1069 if (opts
.seccomp_filter
)
1070 do_seccomp_filter(opts
.seccomp_filter
);
1072 if (prctl(PR_SET_KEEPCAPS
, 1, 0, 0, 0) == -1)
1073 err(EXIT_FAILURE
, _("keep process capabilities failed"));
1075 /* We're going to want CAP_SETPCAP, CAP_SETUID, and CAP_SETGID if
1077 bump_cap(CAP_SETPCAP
);
1078 bump_cap(CAP_SETUID
);
1079 bump_cap(CAP_SETGID
);
1080 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
1081 err(SETPRIV_EXIT_PRIVERR
, _("activate capabilities"));
1083 if (opts
.have_ruid
|| opts
.have_euid
) {
1084 do_setresuid(&opts
);
1085 /* KEEPCAPS doesn't work for the effective mask. */
1086 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
1087 err(SETPRIV_EXIT_PRIVERR
, _("reactivate capabilities"));
1090 if (opts
.have_rgid
|| opts
.have_egid
)
1091 do_setresgid(&opts
);
1093 if (opts
.have_groups
) {
1094 if (setgroups(opts
.num_groups
, opts
.groups
) != 0)
1095 err(SETPRIV_EXIT_PRIVERR
, _("setgroups failed"));
1096 } else if (opts
.init_groups
) {
1097 if (initgroups(opts
.passwd
.pw_name
, opts
.passwd
.pw_gid
) != 0)
1098 err(SETPRIV_EXIT_PRIVERR
, _("initgroups failed"));
1099 } else if (opts
.clear_groups
) {
1101 if (setgroups(0, &x
) != 0)
1102 err(SETPRIV_EXIT_PRIVERR
, _("setgroups failed"));
1105 if (opts
.have_securebits
&& prctl(PR_SET_SECUREBITS
, opts
.securebits
, 0, 0, 0) != 0)
1106 err(SETPRIV_EXIT_PRIVERR
, _("set process securebits failed"));
1108 if (opts
.bounding_set
) {
1109 do_caps(CAP_TYPE_BOUNDING
, opts
.bounding_set
);
1110 errno
= EPERM
; /* capng doesn't set errno if we're missing CAP_SETPCAP */
1111 if (capng_apply(CAPNG_SELECT_BOUNDS
) != 0)
1112 err(SETPRIV_EXIT_PRIVERR
, _("apply bounding set"));
1115 if (opts
.caps_to_inherit
) {
1116 do_caps(CAP_TYPE_INHERITABLE
, opts
.caps_to_inherit
);
1117 if (capng_apply(CAPNG_SELECT_CAPS
) != 0)
1118 err(SETPRIV_EXIT_PRIVERR
, _("apply capabilities"));
1121 if (opts
.ambient_caps
) {
1122 do_caps(CAP_TYPE_AMBIENT
, opts
.ambient_caps
);
1125 /* Clear or set parent death signal */
1126 if (opts
.pdeathsig
&& prctl(PR_SET_PDEATHSIG
, opts
.pdeathsig
< 0 ? 0 : opts
.pdeathsig
) != 0)
1127 err(SETPRIV_EXIT_PRIVERR
, _("set parent death signal failed"));
1129 do_landlock(&opts
.landlock
);
1131 execvp(argv
[optind
], argv
+ optind
);
1132 errexec(argv
[optind
]);