Date: Tue, 9 Feb 2021 08:36:48 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: a7c9e79f70e8 - stable/12 - pgrp: Prevent use after free. Message-ID: <202102090836.1198amvk013825@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=a7c9e79f70e865909970aafa4a1ca9f5e50b168d commit a7c9e79f70e865909970aafa4a1ca9f5e50b168d Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2020-12-31 13:44:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-02-09 08:35:28 +0000 pgrp: Prevent use after free. Tested by: pho (cherry picked from commit ef739c7373d8b3833979ad471b31cb9e215411fd) --- sys/kern/kern_proc.c | 20 +++++++++++++++----- sys/kern/kern_prot.c | 13 +++++-------- sys/sys/proc.h | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 04d82d30f8c2..4a202f0a7411 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -103,7 +103,6 @@ SDT_PROBE_DEFINE3(proc, , dtor, return, "struct proc *", "int", "void *"); SDT_PROBE_DEFINE3(proc, , init, entry, "struct proc *", "int", "int"); SDT_PROBE_DEFINE3(proc, , init, return, "struct proc *", "int", "int"); -MALLOC_DEFINE(M_PGRP, "pgrp", "process group header"); MALLOC_DEFINE(M_SESSION, "session", "session header"); static MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); @@ -117,6 +116,7 @@ static void fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread); static void pgadjustjobc(struct pgrp *pgrp, bool entering); static void pgdelete(struct pgrp *); +static int pgrp_init(void *mem, int size, int flags); static int proc_ctor(void *mem, int size, void *arg, int flags); static void proc_dtor(void *mem, int size, void *arg); static int proc_init(void *mem, int size, int flags); @@ -137,6 +137,7 @@ struct sx __exclusive_cache_line allproc_lock; struct sx __exclusive_cache_line proctree_lock; struct mtx __exclusive_cache_line ppeers_lock; uma_zone_t proc_zone; +uma_zone_t pgrp_zone; /* * The offset of various fields in struct proc and struct thread. @@ -194,6 +195,8 @@ procinit(void) proc_zone = uma_zcreate("PROC", sched_sizeof_proc(), proc_ctor, proc_dtor, proc_init, proc_fini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + pgrp_zone = uma_zcreate("PGRP", sizeof(struct pgrp), NULL, NULL, + pgrp_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uihashinit(); } @@ -297,6 +300,16 @@ proc_fini(void *mem, int size) #endif } +static int +pgrp_init(void *mem, int size, int flags) +{ + struct pgrp *pg; + + pg = mem; + mtx_init(&pg->pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); + return (0); +} + /* * Is p an inferior of the current process? */ @@ -476,8 +489,6 @@ enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, struct session *sess) KASSERT(!SESS_LEADER(p), ("enterpgrp: session leader attempted setpgrp")); - mtx_init(&pgrp->pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); - if (sess != NULL) { /* * new session @@ -701,8 +712,7 @@ pgdelete(struct pgrp *pgrp) tty_rel_pgrp(tp, pgrp); } - mtx_destroy(&pgrp->pg_mtx); - free(pgrp, M_PGRP); + uma_zfree(pgrp_zone, pgrp); sess_release(savesess); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index a62b6f76da74..0f4814c59e78 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -325,7 +325,7 @@ sys_setsid(struct thread *td, struct setsid_args *uap) error = 0; pgrp = NULL; - newpgrp = malloc(sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); + newpgrp = uma_zalloc(pgrp_zone, M_WAITOK); newsess = malloc(sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO); sx_xlock(&proctree_lock); @@ -343,10 +343,8 @@ sys_setsid(struct thread *td, struct setsid_args *uap) sx_xunlock(&proctree_lock); - if (newpgrp != NULL) - free(newpgrp, M_PGRP); - if (newsess != NULL) - free(newsess, M_SESSION); + uma_zfree(pgrp_zone, newpgrp); + free(newsess, M_SESSION); return (error); } @@ -385,7 +383,7 @@ sys_setpgid(struct thread *td, struct setpgid_args *uap) error = 0; - newpgrp = malloc(sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); + newpgrp = uma_zalloc(pgrp_zone, M_WAITOK); sx_xlock(&proctree_lock); if (uap->pid != 0 && uap->pid != curp->p_pid) { @@ -448,8 +446,7 @@ done: sx_xunlock(&proctree_lock); KASSERT((error == 0) || (newpgrp != NULL), ("setpgid failed and newpgrp is NULL")); - if (newpgrp != NULL) - free(newpgrp, M_PGRP); + uma_zfree(pgrp_zone, newpgrp); return (error); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a12646c951c5..9784d26a1215 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -841,7 +841,6 @@ struct proc { #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_PARGS); -MALLOC_DECLARE(M_PGRP); MALLOC_DECLARE(M_SESSION); MALLOC_DECLARE(M_SUBPROC); #endif @@ -1011,6 +1010,7 @@ extern struct proclist zombproc; /* List of zombie processes. */ extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */ extern struct uma_zone *proc_zone; +extern struct uma_zone *pgrp_zone; struct proc *pfind(pid_t); /* Find process by id. */ struct proc *pfind_any(pid_t); /* Find (zombie) process by id. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102090836.1198amvk013825>