From 18b4c2bbe82bef16aa24e9194dca1e2b55cfd3fa Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 12 Aug 2010 21:11:20 -0700 Subject: [PATCH] kernel - Add sysref assertions * Add checks in the sysref code to detect use-after-free situations. --- sys/kern/kern_sysref.c | 7 ++++++- sys/sys/sysref.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_sysref.c b/sys/kern/kern_sysref.c index f9250ec975..96b748e250 100644 --- a/sys/kern/kern_sysref.c +++ b/sys/kern/kern_sysref.c @@ -153,6 +153,8 @@ sysref_alloc(struct sysref_class *srclass) */ data = objcache_get(srclass->oc, M_WAITOK); sr = (struct sysref *)(data + srclass->offset); + KKASSERT(sr->flags & SRF_PUTAWAY); + sr->flags &= ~SRF_PUTAWAY; /* * Refcnt isn't touched while it is zero. The objcache ctor @@ -216,7 +218,7 @@ sysref_ctor(void *data, void *privdata, int ocflags) sr->sysid = gd->gd_sysid_alloc; KKASSERT(((int)sr->sysid & ncpus_fit_mask) == gd->gd_cpuid); /* sr->refcnt= 0; already zero */ - sr->flags = SRF_ALLOCATED; + sr->flags = SRF_ALLOCATED | SRF_PUTAWAY; sr->srclass = srclass; sa = &sysref_array[gd->gd_cpuid]; @@ -299,6 +301,8 @@ _sysref_put(struct sysref *sr) int count; void *data; + KKASSERT((sr->flags & SRF_PUTAWAY) == 0); + for (;;) { count = sr->refcnt; if (count > 1) { @@ -341,6 +345,7 @@ _sysref_put(struct sysref *sr) KKASSERT(count == -0x40000000); if (atomic_cmpset_int(&sr->refcnt, count, 0)) { KKASSERT(sr->flags & SRF_ALLOCATED); + sr->flags |= SRF_PUTAWAY; data = (char *)sr - sr->srclass->offset; if (sr->flags & SRF_SYSIDUSED) objcache_dtor(sr->srclass->oc, data); diff --git a/sys/sys/sysref.h b/sys/sys/sysref.h index a496d77a77..7afc2dc13e 100644 --- a/sys/sys/sysref.h +++ b/sys/sys/sysref.h @@ -116,6 +116,7 @@ struct sysref { #define SRF_SYSIDUSED 0x0001 /* sysid was used for access */ #define SRF_ALLOCATED 0x0002 /* sysref_alloc used to allocate */ +#define SRF_PUTAWAY 0x0004 /* in objcache */ RB_HEAD(sysref_rb_tree, sysref); RB_PROTOTYPE2(sysref_rb_tree, sysref, rbnode, rb_sysref_compare, sysid_t); -- 2.41.0