Module Name: src Committed By: christos Date: Fri Mar 1 03:03:19 UTC 2019
Modified Files: src/sys/kern: kern_uidinfo.c uipc_sem.c src/sys/sys: param.h proc.h uidinfo.h Log Message: PR/53998: Joel Bertrand: Limit the number of semaphores on a per-user basis not a per-process. We cannot really keep track on a per-process basis because a parent process can create the semaphore and a child can free it taking credit for it. There is also a similar issue about resource exhaustion if we limited the number of lwps per process as opposed to per user (which we don't). To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/kern/kern_uidinfo.c cvs rdiff -u -r1.54 -r1.55 src/sys/kern/uipc_sem.c cvs rdiff -u -r1.582 -r1.583 src/sys/sys/param.h cvs rdiff -u -r1.350 -r1.351 src/sys/sys/proc.h cvs rdiff -u -r1.3 -r1.4 src/sys/sys/uidinfo.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_uidinfo.c diff -u src/sys/kern/kern_uidinfo.c:1.10 src/sys/kern/kern_uidinfo.c:1.11 --- src/sys/kern/kern_uidinfo.c:1.10 Sat Mar 18 01:49:56 2017 +++ src/sys/kern/kern_uidinfo.c Thu Feb 28 22:03:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_uidinfo.c,v 1.10 2017/03/18 05:49:56 riastradh Exp $ */ +/* $NetBSD: kern_uidinfo.c,v 1.11 2019/03/01 03:03:19 christos Exp $ */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_uidinfo.c,v 1.10 2017/03/18 05:49:56 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_uidinfo.c,v 1.11 2019/03/01 03:03:19 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -63,6 +63,7 @@ sysctl_kern_uidinfo_cnt(SYSCTLFN_ARGS) _MEM(proccnt), _MEM(lwpcnt), _MEM(lockcnt), + _MEM(semcnt), _MEM(sbsize), #undef _MEM }; @@ -119,6 +120,12 @@ sysctl_kern_uidinfo_setup(void) CTL_CREATE, CTL_EOL); sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode, CTLFLAG_PERMANENT, + CTLTYPE_QUAD, "semcnt", + SYSCTL_DESCR("Number of semaphores used for the current user"), + sysctl_kern_uidinfo_cnt, 0, NULL, 0, + CTL_CREATE, CTL_EOL); + sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode, + CTLFLAG_PERMANENT, CTLTYPE_QUAD, "sbsize", SYSCTL_DESCR("Socket buffers used for the current user"), sysctl_kern_uidinfo_cnt, 0, NULL, 0, @@ -219,6 +226,22 @@ chglwpcnt(uid_t uid, int diff) return lwpcnt; } +/* + * Change the count associated with number of semaphores + * a given user is using. + */ +int +chgsemcnt(uid_t uid, int diff) +{ + struct uidinfo *uip; + long semcnt; + + uip = uid_find(uid); + semcnt = atomic_add_long_nv(&uip->ui_semcnt, diff); + KASSERT(semcnt >= 0); + return semcnt; +} + int chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t xmax) { Index: src/sys/kern/uipc_sem.c diff -u src/sys/kern/uipc_sem.c:1.54 src/sys/kern/uipc_sem.c:1.55 --- src/sys/kern/uipc_sem.c:1.54 Thu Feb 21 16:49:23 2019 +++ src/sys/kern/uipc_sem.c Thu Feb 28 22:03:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_sem.c,v 1.54 2019/02/21 21:49:23 christos Exp $ */ +/* $NetBSD: uipc_sem.c,v 1.55 2019/03/01 03:03:19 christos Exp $ */ /*- * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_sem.c,v 1.54 2019/02/21 21:49:23 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_sem.c,v 1.55 2019/03/01 03:03:19 christos Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -85,6 +85,7 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_sem.c,v #include <sys/syscallargs.h> #include <sys/syscallvar.h> #include <sys/sysctl.h> +#include <sys/uidinfo.h> #include <sys/cprng.h> MODULE(MODULE_CLASS_MISC, ksem, NULL); @@ -467,8 +468,10 @@ ksem_create(lwp_t *l, const char *name, len = 0; } - if (atomic_inc_uint_nv(&l->l_proc->p_nsems) > SEM_NSEMS_MAX) { - atomic_dec_uint(&l->l_proc->p_nsems); + u_int cnt; + uid_t uid = kauth_cred_getuid(l->l_cred); + if ((cnt = chgsemcnt(uid, 1)) > SEM_NSEMS_MAX) { + chgsemcnt(uid, -1); if (kname != NULL) kmem_free(kname, len); return ENOSPC; @@ -511,7 +514,7 @@ ksem_free(ksem_t *ks) kmem_free(ks, sizeof(ksem_t)); atomic_dec_uint(&nsems_total); - atomic_dec_uint(&curproc->p_nsems); + chgsemcnt(kauth_cred_getuid(curproc->p_cred), -1); } #define KSEM_ID_IS_PSHARED(id) \ Index: src/sys/sys/param.h diff -u src/sys/sys/param.h:1.582 src/sys/sys/param.h:1.583 --- src/sys/sys/param.h:1.582 Sun Feb 3 03:02:25 2019 +++ src/sys/sys/param.h Thu Feb 28 22:03:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.582 2019/02/03 08:02:25 pgoyette Exp $ */ +/* $NetBSD: param.h,v 1.583 2019/03/01 03:03:19 christos Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -67,7 +67,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 899003400 /* NetBSD 8.99.34 */ +#define __NetBSD_Version__ 899003500 /* NetBSD 8.99.35 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) Index: src/sys/sys/proc.h diff -u src/sys/sys/proc.h:1.350 src/sys/sys/proc.h:1.351 --- src/sys/sys/proc.h:1.350 Wed Dec 5 13:16:51 2018 +++ src/sys/sys/proc.h Thu Feb 28 22:03:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.350 2018/12/05 18:16:51 christos Exp $ */ +/* $NetBSD: proc.h,v 1.351 2019/03/01 03:03:19 christos Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -316,7 +316,6 @@ struct proc { pid_t p_vfpid_done; /* :: vforked done pid */ lwpid_t p_lwp_created; /* :: lwp created */ lwpid_t p_lwp_exited; /* :: lwp exited */ - u_int p_nsems; /* Count of semaphores */ char *p_path; /* :: full pathname of executable */ /* @@ -338,7 +337,6 @@ struct proc { vaddr_t p_psstrp; /* :: address of process's ps_strings */ u_int p_pax; /* :: PAX flags */ - int p_xexit; /* p: exit code */ /* * End area that is copied on creation Index: src/sys/sys/uidinfo.h diff -u src/sys/sys/uidinfo.h:1.3 src/sys/sys/uidinfo.h:1.4 --- src/sys/sys/uidinfo.h:1.3 Fri Jun 8 22:31:15 2012 +++ src/sys/sys/uidinfo.h Thu Feb 28 22:03:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: uidinfo.h,v 1.3 2012/06/09 02:31:15 christos Exp $ */ +/* $NetBSD: uidinfo.h,v 1.4 2019/03/01 03:03:19 christos Exp $ */ /* * Copyright (c) 1991, 1993 @@ -45,11 +45,13 @@ struct uidinfo { u_long ui_proccnt; /* Number of processes */ u_long ui_lwpcnt; /* Number of lwps */ u_long ui_lockcnt; /* Number of locks */ + u_long ui_semcnt; /* Number of semaphores */ u_long ui_sbsize; /* Socket buffer size */ }; int chgproccnt(uid_t, int); int chglwpcnt(uid_t, int); +int chgsemcnt(uid_t, int); int chgsbsize(struct uidinfo *, u_long *, u_long, rlim_t); struct uidinfo *uid_find(uid_t); void uid_init(void);