From cfe5e3905201349e9cf3f95d52ff4bd100bde37d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 21:10:49 +0200 Subject: Adding upstream version 2.39.3. Signed-off-by: Daniel Baumann --- sys-utils/setpriv.c | 1061 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1061 insertions(+) create mode 100644 sys-utils/setpriv.c (limited to 'sys-utils/setpriv.c') diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c new file mode 100644 index 0000000..ddc2cc6 --- /dev/null +++ b/sys-utils/setpriv.c @@ -0,0 +1,1061 @@ +/* + * setpriv(1) - set various kernel privilege bits and run something + * + * Copyright (C) 2012 Andy Lutomirski + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "c.h" +#include "caputils.h" +#include "closestream.h" +#include "nls.h" +#include "optutils.h" +#include "strutils.h" +#include "xalloc.h" +#include "pathnames.h" +#include "signames.h" +#include "env.h" + +#ifndef PR_SET_NO_NEW_PRIVS +# define PR_SET_NO_NEW_PRIVS 38 +#endif +#ifndef PR_GET_NO_NEW_PRIVS +# define PR_GET_NO_NEW_PRIVS 39 +#endif + +#define SETPRIV_EXIT_PRIVERR 127 /* how we exit when we fail to set privs */ + +/* The shell to set SHELL env.variable if none is given in the user's passwd entry. */ +#define DEFAULT_SHELL "/bin/sh" + +static gid_t get_group(const char *s, const char *err); + +enum cap_type { + CAP_TYPE_EFFECTIVE = CAPNG_EFFECTIVE, + CAP_TYPE_PERMITTED = CAPNG_PERMITTED, + CAP_TYPE_INHERITABLE = CAPNG_INHERITABLE, + CAP_TYPE_BOUNDING = CAPNG_BOUNDING_SET, + CAP_TYPE_AMBIENT = (1 << 4) +}; + +/* + * Note: We are subject to https://bugzilla.redhat.com/show_bug.cgi?id=895105 + * and we will therefore have problems if new capabilities are added. Once + * that bug is fixed, I'll (Andy Lutomirski) submit a corresponding fix to + * setpriv. In the mean time, the code here tries to work reasonably well. + */ + +struct privctx { + unsigned int + nnp:1, /* no_new_privs */ + have_ruid:1, /* real uid */ + have_euid:1, /* effective uid */ + have_rgid:1, /* real gid */ + have_egid:1, /* effective gid */ + have_passwd:1, /* passwd entry */ + have_groups:1, /* add groups */ + keep_groups:1, /* keep groups */ + clear_groups:1, /* remove groups */ + init_groups:1, /* initialize groups */ + reset_env:1, /* reset environment */ + have_securebits:1; /* remove groups */ + + /* uids and gids */ + uid_t ruid, euid; + gid_t rgid, egid; + + /* real user passwd entry */ + struct passwd passwd; + + /* supplementary groups */ + size_t num_groups; + gid_t *groups; + + /* caps */ + const char *caps_to_inherit; + const char *ambient_caps; + const char *bounding_set; + + /* securebits */ + int securebits; + /* parent death signal (<0 clear, 0 nothing, >0 signal) */ + int pdeathsig; + + /* LSMs */ + const char *selinux_label; + const char *apparmor_profile; +}; + +static void __attribute__((__noreturn__)) usage(void) +{ + FILE *out = stdout; + fputs(USAGE_HEADER, out); + fprintf(out, _(" %s [options] [...]\n"), + program_invocation_short_name); + + fputs(USAGE_SEPARATOR, out); + fputs(_("Run a program with different privilege settings.\n"), out); + + fputs(USAGE_OPTIONS, out); + fputs(_(" -d, --dump show current state (and do not exec)\n"), out); + fputs(_(" --nnp, --no-new-privs disallow granting new privileges\n"), out); + fputs(_(" --ambient-caps set ambient capabilities\n"), out); + fputs(_(" --inh-caps set inheritable capabilities\n"), out); + fputs(_(" --bounding-set set capability bounding set\n"), out); + fputs(_(" --ruid set real uid\n"), out); + fputs(_(" --euid set effective uid\n"), out); + fputs(_(" --rgid set real gid\n"), out); + fputs(_(" --egid set effective gid\n"), out); + fputs(_(" --reuid set real and effective uid\n"), out); + fputs(_(" --regid set real and effective gid\n"), out); + fputs(_(" --clear-groups clear supplementary groups\n"), out); + fputs(_(" --keep-groups keep supplementary groups\n"), out); + fputs(_(" --init-groups initialize supplementary groups\n"), out); + fputs(_(" --groups set supplementary groups by UID or name\n"), out); + fputs(_(" --securebits set securebits\n"), out); + fputs(_(" --pdeathsig keep|clear|\n" + " set or clear parent death signal\n"), out); + fputs(_(" --selinux-label