summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-26 13:43:52 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-26 13:43:52 +0000
commitc2d500a03014df2765fd74b312041858dbd9120c (patch)
tree0023877e00d8597d47e4c9f81a3deb4e8b48de83 /sys
parentf0e5d780571f3d31e460f047c6dce20f36b1cd91 (diff)
Serialize access to UID data with a rwlock.
Caller must call uid_release() after making whatever change they needed on the result of uid_find(). Adapted from guenther@'s proctree diff, ok dlg@, visa@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_proc.c26
-rw-r--r--sys/kern/vfs_lockf.c8
-rw-r--r--sys/sys/proc.h3
3 files changed, 30 insertions, 7 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 8ba12226f0d..45e84d8462d 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.81 2018/02/20 12:38:58 mpi Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.82 2018/02/26 13:43:51 mpi Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -39,6 +39,7 @@
#include <sys/buf.h>
#include <sys/acct.h>
#include <sys/wait.h>
+#include <sys/rwlock.h>
#include <ufs/ufs/quota.h>
#include <sys/uio.h>
#include <sys/malloc.h>
@@ -49,6 +50,7 @@
#include <sys/pool.h>
#include <sys/vnode.h>
+struct rwlock uidinfolk;
#define UIHASH(uid) (&uihashtbl[(uid) & uihash])
LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
u_long uihash; /* size of hash table - 1 */
@@ -91,6 +93,7 @@ procinit(void)
LIST_INIT(&zombprocess);
LIST_INIT(&allproc);
+ rw_init(&uidinfolk, "uidinfo");
tidhashtbl = hashinit(maxthread / 4, M_PROC, M_NOWAIT, &tidhash);
pidhashtbl = hashinit(maxprocess / 4, M_PROC, M_NOWAIT, &pidhash);
@@ -113,6 +116,10 @@ procinit(void)
PR_WAITOK, "sessionpl", NULL);
}
+/*
+ * This returns with `uidinfolk' held: caller must call uid_release()
+ * after making whatever change they needed.
+ */
struct uidinfo *
uid_find(uid_t uid)
{
@@ -120,12 +127,15 @@ uid_find(uid_t uid)
struct uihashhead *uipp;
uipp = UIHASH(uid);
+ rw_enter_write(&uidinfolk);
LIST_FOREACH(uip, uipp, ui_hash)
if (uip->ui_uid == uid)
break;
if (uip)
return (uip);
+ rw_exit_write(&uidinfolk);
nuip = malloc(sizeof(*nuip), M_PROC, M_WAITOK|M_ZERO);
+ rw_enter_write(&uidinfolk);
LIST_FOREACH(uip, uipp, ui_hash)
if (uip->ui_uid == uid)
break;
@@ -139,6 +149,12 @@ uid_find(uid_t uid)
return (nuip);
}
+void
+uid_release(struct uidinfo *uip)
+{
+ rw_exit_write(&uidinfolk);
+}
+
/*
* Change the count associated with number of threads
* a given user is using.
@@ -147,12 +163,14 @@ int
chgproccnt(uid_t uid, int diff)
{
struct uidinfo *uip;
+ long count;
uip = uid_find(uid);
- uip->ui_proccnt += diff;
- if (uip->ui_proccnt < 0)
+ count = (uip->ui_proccnt += diff);
+ uid_release(uip);
+ if (count < 0)
panic("chgproccnt: procs < 0");
- return (uip->ui_proccnt);
+ return count;
}
/*
diff --git a/sys/kern/vfs_lockf.c b/sys/kern/vfs_lockf.c
index 019090005be..9bd95aede32 100644
--- a/sys/kern/vfs_lockf.c
+++ b/sys/kern/vfs_lockf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_lockf.c,v 1.24 2016/11/07 00:26:33 guenther Exp $ */
+/* $OpenBSD: vfs_lockf.c,v 1.25 2018/02/26 13:43:51 mpi Exp $ */
/* $NetBSD: vfs_lockf.c,v 1.7 1996/02/04 02:18:21 christos Exp $ */
/*
@@ -106,9 +106,12 @@ lf_alloc(uid_t uid, int allowfail)
uip = uid_find(uid);
if (uid && allowfail && uip->ui_lockcnt >
- (allowfail == 1 ? maxlocksperuid : (maxlocksperuid * 2)))
+ (allowfail == 1 ? maxlocksperuid : (maxlocksperuid * 2))) {
+ uid_release(uip);
return (NULL);
+ }
uip->ui_lockcnt++;
+ uid_release(uip);
lock = pool_get(&lockfpool, PR_WAITOK);
lock->lf_uid = uid;
return (lock);
@@ -121,6 +124,7 @@ lf_free(struct lockf *lock)
uip = uid_find(lock->lf_uid);
uip->ui_lockcnt--;
+ uid_release(uip);
pool_put(&lockfpool, lock);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index fd0e46e5984..edcaf7cb960 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.246 2018/02/20 12:38:58 mpi Exp $ */
+/* $OpenBSD: proc.h,v 1.247 2018/02/26 13:43:51 mpi Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -408,6 +408,7 @@ struct uidinfo {
};
struct uidinfo *uid_find(uid_t);
+void uid_release(struct uidinfo *);
/*
* We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t,