summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2018-06-21 13:58:21 +0000
committervisa <visa@openbsd.org>2018-06-21 13:58:21 +0000
commit0ff991d2469a5e6b2ec82348ccae67e31455ec55 (patch)
treea2c3a76c752e360bc0c5b8e1bd312d11b5d02f3a /sys
parentShuffle fields around to eliminate blanks spots resulting from (diff)
downloadwireguard-openbsd-0ff991d2469a5e6b2ec82348ccae67e31455ec55.tar.xz
wireguard-openbsd-0ff991d2469a5e6b2ec82348ccae67e31455ec55.zip
Use atomic operations for updating cred structure reference counts
to make crfree() and crhold() MP-safe. Make crhold() a proper function. Put the definition into file kern_prot.c to constrain the need of the <sys/atomic.h> header. While there, adjust the IPL of ucred_pool to avoid lock order problems with the kernel lock (pointed out by kettenis@). OK mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_proc.c4
-rw-r--r--sys/kern/kern_prot.c16
-rw-r--r--sys/sys/ucred.h4
3 files changed, 18 insertions, 6 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index def3f768d89..0ce3d285796 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.83 2018/03/27 08:42:49 mpi Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.84 2018/06/21 13:58:21 visa Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -108,7 +108,7 @@ procinit(void)
PR_WAITOK, "processpl", NULL);
pool_init(&rusage_pool, sizeof(struct rusage), 0, IPL_NONE,
PR_WAITOK, "zombiepl", NULL);
- pool_init(&ucred_pool, sizeof(struct ucred), 0, IPL_NONE,
+ pool_init(&ucred_pool, sizeof(struct ucred), 0, IPL_MPFLOOR,
PR_WAITOK, "ucredpl", NULL);
pool_init(&pgrp_pool, sizeof(struct pgrp), 0, IPL_NONE,
PR_WAITOK, "pgrppl", NULL);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index ec7ac4d4f32..5622d3b3c94 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_prot.c,v 1.73 2018/02/20 12:38:58 mpi Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.74 2018/06/21 13:58:21 visa Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
@@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/acct.h>
+#include <sys/atomic.h>
#include <sys/systm.h>
#include <sys/ucred.h>
#include <sys/proc.h>
@@ -948,6 +949,17 @@ crget(void)
}
/*
+ * Increment the reference count of a cred structure.
+ * Return the passed structure.
+ */
+struct ucred *
+crhold(struct ucred *cr)
+{
+ atomic_inc_int(&cr->cr_ref);
+ return (cr);
+}
+
+/*
* Free a cred structure.
* Throws away space when ref count gets to 0.
*/
@@ -955,7 +967,7 @@ void
crfree(struct ucred *cr)
{
- if (--cr->cr_ref == 0)
+ if (atomic_dec_int_nv(&cr->cr_ref) == 0)
pool_put(&ucred_pool, cr);
}
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index 03e023dc04a..7ce0fd60b2c 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ucred.h,v 1.12 2018/02/19 08:59:53 mpi Exp $ */
+/* $OpenBSD: ucred.h,v 1.13 2018/06/21 13:58:21 visa Exp $ */
/* $NetBSD: ucred.h,v 1.12 1995/06/01 22:44:50 jtc Exp $ */
/*
@@ -68,7 +68,6 @@ struct xucred {
};
#ifdef _KERNEL
-#define crhold(cr) (cr)->cr_ref++
int crfromxucred(struct ucred *, const struct xucred *);
void crset(struct ucred *, const struct ucred *);
@@ -76,6 +75,7 @@ struct ucred *crcopy(struct ucred *cr);
struct ucred *crdup(struct ucred *cr);
void crfree(struct ucred *cr);
struct ucred *crget(void);
+struct ucred *crhold(struct ucred *);
int suser(struct proc *p);
int suser_ucred(struct ucred *cred);