**--pdeathsig keep**|**clear**|*<signal>*::
Keep, clear or set the parent death signal. Some LSMs, most notably SELinux and AppArmor, clear the signal when the process' credentials change. Using *--pdeathsig keep* will restore the parent death signal after changing credentials to remedy that situation.
+*--ptracer* _pid_|**any**|**none**::
+When Yama's restricted ptrace mode is in effect (that is, when _/proc/sys/kernel/yama/ptrace_scope_ is set to 1), allow being traced via **ptrace**(2) by the process with the specified PID, or any process, or no process. See **PR_SET_PTRACER**(2const). (Note that this is not inherited by child processes, though it is preserved across **execve**(2).) This option has no effect when Yama is not enabled or is in a mode other than restricted ptrace.
+
*--selinux-label* _label_::
Request a particular SELinux transition (using a transition on exec, not dyntrans). This will fail and cause *setpriv* to abort if SELinux is not in use, and the transition may be ignored or cause *execve*(2) to fail at SELinux's whim. (In particular, this is unlikely to work in conjunction with _no_new_privs_.) This is similar to *runcon*(1).
clear_groups:1, /* remove groups */
init_groups:1, /* initialize groups */
reset_env:1, /* reset environment */
- have_securebits:1; /* remove groups */
+ have_securebits:1, /* remove groups */
+ have_ptracer:1; /* modify ptracer */
/* uids and gids */
uid_t ruid, euid;
/* parent death signal (<0 clear, 0 nothing, >0 signal) */
int pdeathsig;
+ /* permitted ptracer under Yama mode 1 */
+ long ptracer;
+
/* LSMs */
const char *selinux_label;
const char *apparmor_profile;
fputs(_(" --securebits <bits> set securebits\n"), out);
fputs(_(" --pdeathsig keep|clear|<signame>\n"
" set or clear parent death signal\n"), out);
+ fputs(_(" --ptracer <pid>|any|none allow ptracing from the given process\n"), out);
fputs(_(" --selinux-label <label> set SELinux label\n"), out);
fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out);
fputs(_(" --landlock-access <access> add Landlock access\n"), out);
}
}
+static void parse_ptracer(struct privctx *opts, const char *str)
+{
+ if (!strcmp(str, "any")) {
+ opts->ptracer = PR_SET_PTRACER_ANY;
+ } else if (!strcmp(str, "none")) {
+ opts->ptracer = 0;
+ } else {
+ opts->ptracer = strtopid_or_err(str, _("failed to parse ptracer pid"));
+ }
+}
+
static void do_setresuid(const struct privctx *opts)
{
uid_t ruid, euid, suid;
CAPBSET,
SECUREBITS,
PDEATHSIG,
+ PTRACER,
SELINUX_LABEL,
APPARMOR_PROFILE,
LANDLOCK_ACCESS,
{ "bounding-set", required_argument, NULL, CAPBSET },
{ "securebits", required_argument, NULL, SECUREBITS },
{ "pdeathsig", required_argument, NULL, PDEATHSIG, },
+ { "ptracer", required_argument, NULL, PTRACER, },
{ "selinux-label", required_argument, NULL, SELINUX_LABEL },
{ "apparmor-profile", required_argument, NULL, APPARMOR_PROFILE },
{ "landlock-access", required_argument, NULL, LANDLOCK_ACCESS },
_("duplicate --keep-pdeathsig option"));
parse_pdeathsig(&opts, optarg);
break;
+ case PTRACER:
+ if (opts.have_ptracer)
+ errx(EXIT_FAILURE,
+ _("duplicate --ptracer option"));
+ opts.have_ptracer = 1;
+ parse_ptracer(&opts, optarg);
+ break;
case LISTCAPS:
list_caps = 1;
break;
if (opts.pdeathsig && prctl(PR_SET_PDEATHSIG, opts.pdeathsig < 0 ? 0 : opts.pdeathsig) != 0)
err(SETPRIV_EXIT_PRIVERR, _("set parent death signal failed"));
+ if (opts.have_ptracer) {
+ if (prctl(PR_SET_PTRACER, opts.ptracer) < 0) {
+ err(SETPRIV_EXIT_PRIVERR, _("set ptracer"));
+ }
+ }
+
do_landlock(&opts.landlock);
execvp(argv[optind], argv + optind);