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