[PATCH] refcount: Use CONFIG_BUG_ON_DATA_CORRUPTION for UAF-related errors

Jann Horn <[email protected]>
Newsgroups org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel
Message-ID <20260812-refcount-bug-on-data-corruption-v1-1-c6da63566101@google.com>
Some refcount issues are not necessarily associated with memory corruption,
but REFCOUNT_ADD_UAF suggests that a UAF either just happened or is about
to happen.

REFCOUNT_SUB_UAF is also an indicator that reference counting is wrong, and
suggests (less strongly) that a UAF access might have happened recently.

In these cases, BUG() is appropriate if CONFIG_BUG_ON_DATA_CORRUPTION is
set.

Signed-off-by: Jann Horn <[email protected]>
---
MAINTAINERS specifies no specific maintainer for lib/refcount.c, but it
does have an entry for include/linux/refcount.h, so I guess I should
route this patch based on that.

I decided to send this patch after wondering how exploitable it would be
to have a refcount_inc() call on an object which has reached refcount 0,
but is not yet freed because of something like an RCU grace period.
---
 lib/refcount.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/refcount.c b/lib/refcount.c
index a207a8f22b3c..c0f0dc5296eb 100644
--- a/lib/refcount.c
+++ b/lib/refcount.c
@@ -10,6 +10,15 @@
 
 #define REFCOUNT_WARN(str)	WARN_ONCE(1, "refcount_t: " str ".\n")
 
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+#define REFCOUNT_CORRUPTION(str) ({		\
+	pr_err("refcount_t: " str ".\n");	\
+	BUG();					\
+})
+#else
+#define REFCOUNT_CORRUPTION(str) REFCOUNT_WARN(str)
+#endif
+
 void refcount_warn_saturate(refcount_t *r, enum refcount_saturation_type t)
 {
 	refcount_set(r, REFCOUNT_SATURATED);
@@ -22,10 +31,10 @@ void refcount_warn_saturate(refcount_t *r, enum refcount_saturation_type t)
 		REFCOUNT_WARN("saturated; leaking memory");
 		break;
 	case REFCOUNT_ADD_UAF:
-		REFCOUNT_WARN("addition on 0; use-after-free");
+		REFCOUNT_CORRUPTION("addition on 0; use-after-free");
 		break;
 	case REFCOUNT_SUB_UAF:
-		REFCOUNT_WARN("underflow; use-after-free");
+		REFCOUNT_CORRUPTION("underflow; use-after-free");
 		break;
 	case REFCOUNT_DEC_LEAK:
 		REFCOUNT_WARN("decrement hit 0; leaking memory");
@@ -84,7 +93,7 @@ bool refcount_dec_not_one(refcount_t *r)
 
 		new = val - 1;
 		if (new > val) {
-			WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
+			REFCOUNT_CORRUPTION("underflow; use-after-free");
 			return true;
 		}
 

---
base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
change-id: 20260812-refcount-bug-on-data-corruption-f1a566f771e6

Best regards,
--  
Jann Horn <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.