Date: Fri, 24 Sep 2021 00:40:03 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: e79a18dadf83 - stable/13 - procctl(2): add PROC_NO_NEW_PRIVS_CTL, PROC_NO_NEW_PRIVS_STATUS Message-ID: <202109240040.18O0e3vv050767@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e79a18dadf83b7bdcab1c2ba8b43b9a508810d22 commit e79a18dadf83b7bdcab1c2ba8b43b9a508810d22 Author: Edward Tomasz Napierala <trasz@FreeBSD.org> AuthorDate: 2021-07-01 08:11:11 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-09-24 00:26:59 +0000 procctl(2): add PROC_NO_NEW_PRIVS_CTL, PROC_NO_NEW_PRIVS_STATUS (cherry picked from commit db8d680ebe9b12c7d9e0eb8bf9940fcef709f5ec) --- lib/libc/sys/procctl.2 | 27 ++++++++++++++++++++++++++- sys/compat/freebsd32/freebsd32_misc.c | 3 +++ sys/kern/kern_exec.c | 5 +++-- sys/kern/kern_fork.c | 2 +- sys/kern/kern_procctl.c | 32 ++++++++++++++++++++++++++++++++ sys/sys/proc.h | 1 + sys/sys/procctl.h | 5 +++++ 7 files changed, 71 insertions(+), 4 deletions(-) diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index f85825d8cc6f..432ed5919a81 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 13, 2020 +.Dd July 1, 2021 .Dt PROCCTL 2 .Os .Sh NAME @@ -564,6 +564,31 @@ Stack gaps are enabled in the process after Stack gaps are disabled in the process after .Xr execve 2 . .El +.It Dv PROC_NO_NEW_PRIVS_CTL +Allows one to ignore the SUID and SGID bits on the program +images activated by +.Xr execve 2 +in the specified process and its future descendants. +The +.Fa data +parameter must point to the integer variable holding the following +value: +.Bl -tag -width PROC_NO_NEW_PRIVS_ENABLE +.It Dv PROC_NO_NEW_PRIVS_ENABLE +Request SUID and SGID bits to be ignored. +.El +.Pp +It is not possible to disable it once it has been enabled. +.It Dv PROC_NO_NEW_PRIVS_STATUS +Returns the current status of SUID/SGID enablement for the target process. +The +.Fa data +parameter must point to the integer variable, where one of the +following values is written: +.Bl -tag -width PROC_NO_NEW_PRIVS_DISABLE +.It Dv PROC_NO_NEW_PRIVS_ENABLE +.It Dv PROC_NO_NEW_PRIVS_DISABLE +.El .El .Sh x86 MACHINE-SPECIFIC REQUESTS .Bl -tag -width PROC_KPTI_STATUS diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index d258afa2352d..cefae53b69df 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -3631,6 +3631,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap) case PROC_STACKGAP_CTL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_NO_NEW_PRIVS_CTL: error = copyin(PTRIN(uap->data), &flags, sizeof(flags)); if (error != 0) return (error); @@ -3664,6 +3665,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap) case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_NO_NEW_PRIVS_STATUS: data = &flags; break; case PROC_PDEATHSIG_CTL: @@ -3695,6 +3697,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap) case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_NO_NEW_PRIVS_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 491e5332c834..0611eedcec73 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -776,8 +776,9 @@ interpret: signotify(td); } - if (imgp->sysent->sv_setid_allowed != NULL && - !(*imgp->sysent->sv_setid_allowed)(td, imgp)) + if ((imgp->sysent->sv_setid_allowed != NULL && + !(*imgp->sysent->sv_setid_allowed)(td, imgp)) || + (p->p_flag2 & P2_NO_NEW_PRIVS) != 0) execve_nosetid(imgp); /* diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 0d0659b432fe..7a80f7de85d8 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -492,7 +492,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread * p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE | P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC | P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP | - P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC); + P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_NO_NEW_PRIVS); p2->p_swtick = ticks; if (p1->p_flag & P_PROFIL) startprofclock(p2); diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index b2694fd0c32c..68fa4bc0c3ac 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -419,6 +419,27 @@ trapcap_status(struct thread *td, struct proc *p, int *data) return (0); } +static int +no_new_privs_ctl(struct thread *td, struct proc *p, int state) +{ + + PROC_LOCK_ASSERT(p, MA_OWNED); + + if (state != PROC_NO_NEW_PRIVS_ENABLE) + return (EINVAL); + p->p_flag2 |= P2_NO_NEW_PRIVS; + return (0); +} + +static int +no_new_privs_status(struct thread *td, struct proc *p, int *data) +{ + + *data = (p->p_flag2 & P2_NO_NEW_PRIVS) != 0 ? + PROC_NO_NEW_PRIVS_ENABLE : PROC_NO_NEW_PRIVS_DISABLE; + return (0); +} + static int protmax_ctl(struct thread *td, struct proc *p, int state) { @@ -601,6 +622,7 @@ sys_procctl(struct thread *td, struct procctl_args *uap) case PROC_STACKGAP_CTL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_NO_NEW_PRIVS_CTL: error = copyin(uap->data, &flags, sizeof(flags)); if (error != 0) return (error); @@ -632,6 +654,7 @@ sys_procctl(struct thread *td, struct procctl_args *uap) case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_NO_NEW_PRIVS_STATUS: data = &flags; break; case PROC_PDEATHSIG_CTL: @@ -662,6 +685,7 @@ sys_procctl(struct thread *td, struct procctl_args *uap) case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_NO_NEW_PRIVS_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; @@ -711,6 +735,10 @@ kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) return (trapcap_ctl(td, p, *(int *)data)); case PROC_TRAPCAP_STATUS: return (trapcap_status(td, p, data)); + case PROC_NO_NEW_PRIVS_CTL: + return (no_new_privs_ctl(td, p, *(int *)data)); + case PROC_NO_NEW_PRIVS_STATUS: + return (no_new_privs_status(td, p, data)); default: return (EINVAL); } @@ -741,6 +769,8 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) case PROC_TRAPCAP_STATUS: case PROC_PDEATHSIG_CTL: case PROC_PDEATHSIG_STATUS: + case PROC_NO_NEW_PRIVS_CTL: + case PROC_NO_NEW_PRIVS_STATUS: if (idtype != P_PID) return (EINVAL); } @@ -773,6 +803,7 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) case PROC_REAP_KILL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_NO_NEW_PRIVS_CTL: sx_slock(&proctree_lock); tree_locked = true; break; @@ -789,6 +820,7 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_NO_NEW_PRIVS_STATUS: tree_locked = false; break; default: diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 138e763f2f11..15e175bf5aad 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -824,6 +824,7 @@ struct proc { after exec */ #define P2_ITSTOPPED 0x00002000 #define P2_PTRACEREQ 0x00004000 /* Active ptrace req */ +#define P2_NO_NEW_PRIVS 0x00008000 /* Ignore setuid */ /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h index 90fb149830dc..cc0279fb0d08 100644 --- a/sys/sys/procctl.h +++ b/sys/sys/procctl.h @@ -63,6 +63,8 @@ #define PROC_PROTMAX_STATUS 16 /* query implicit PROT_MAX status */ #define PROC_STACKGAP_CTL 17 /* en/dis stack gap on MAP_STACK */ #define PROC_STACKGAP_STATUS 18 /* query stack gap */ +#define PROC_NO_NEW_PRIVS_CTL 19 /* disable setuid/setgid */ +#define PROC_NO_NEW_PRIVS_STATUS 20 /* query suid/sgid disabled status */ /* Operations for PROC_SPROTECT (passed in integer arg). */ #define PPROT_OP(x) ((x) & 0xf) @@ -141,6 +143,9 @@ struct procctl_reaper_kill { #define PROC_STACKGAP_ENABLE_EXEC 0x0004 #define PROC_STACKGAP_DISABLE_EXEC 0x0008 +#define PROC_NO_NEW_PRIVS_ENABLE 1 +#define PROC_NO_NEW_PRIVS_DISABLE 2 + #ifndef _KERNEL __BEGIN_DECLS int procctl(idtype_t, id_t, int, void *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109240040.18O0e3vv050767>