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);

Reply via email to