All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Martin Zaharinov <micron10@gmail.com>
Cc: peterz@infradead.org, netdev <netdev@vger.kernel.org>,
	Paolo Abeni <pabeni@redhat.com>,
	patchwork-bot+netdevbpf@kernel.org,
	Jakub Kicinski <kuba@kernel.org>,
	Stephen Hemminger <stephen@networkplumber.org>,
	kuba+netdrv@kernel.org, dsahern@gmail.com,
	Eric Dumazet <edumazet@google.com>
Subject: Re: Urgent Bug Report Kernel crash 6.5.2
Date: Tue, 12 Dec 2023 19:16:21 +0100	[thread overview]
Message-ID: <87r0jrp9qi.ffs@tglx> (raw)
In-Reply-To: <2B5C19AE-C125-45A3-8C6F-CA6BBC01A6D9@gmail.com>

Martin!

On Sat, Dec 09 2023 at 01:01, Martin Zaharinov wrote:
>> On 9 Dec 2023, at 0:20, Thomas Gleixner <tglx@linutronix.de> wrote:
>> That's definitely not a RCU problem. It's a simple refcount fail.
>> 
> Is this a problem or only simple fail , and is it possible to catch
> what is a problem and fix this fail.

Underaccounting a reference count is potentially Use After Free.

    if (rcuref_put(ref))
       call_rcu(ref....);

So after the grace period is over @ref will be freed. Depending on the
timing the context which does the extra put() might already operate on a
freed object.

How to catch that, that's a good question. There is no instrumentation
so far for this. Below is a straight forward trace_printk() based
tracking of rcurefs, which should help to narrow down the context.

Btw, how easy is this to reproduce?

Thanks,

        tglx
---
--- a/include/linux/rcuref.h
+++ b/include/linux/rcuref.h
@@ -64,8 +64,10 @@ static inline __must_check bool rcuref_g
 	 * Unconditionally increase the reference count. The saturation and
 	 * dead zones provide enough tolerance for this.
 	 */
-	if (likely(!atomic_add_negative_relaxed(1, &ref->refcnt)))
+	if (likely(!atomic_add_negative_relaxed(1, &ref->refcnt))) {
+		trace_printk("get(FASTPATH): %px\n", ref);
 		return true;
+	}
 
 	/* Handle the cases inside the saturation and dead zones */
 	return rcuref_get_slowpath(ref);
@@ -84,8 +86,10 @@ static __always_inline __must_check bool
 	 * Unconditionally decrease the reference count. The saturation and
 	 * dead zones provide enough tolerance for this.
 	 */
-	if (likely(!atomic_add_negative_release(-1, &ref->refcnt)))
+	if (likely(!atomic_add_negative_release(-1, &ref->refcnt))) {
+		trace_printk("put(FASTPATH): %px\n", ref);
 		return false;
+	}
 
 	/*
 	 * Handle the last reference drop and cases inside the saturation
--- a/lib/rcuref.c
+++ b/lib/rcuref.c
@@ -200,6 +200,7 @@ bool rcuref_get_slowpath(rcuref_t *ref)
 	 */
 	if (cnt >= RCUREF_RELEASED) {
 		atomic_set(&ref->refcnt, RCUREF_DEAD);
+		trace_printk("get(DEAD): %px %pS\n", ref, __builtin_return_address(0));
 		return false;
 	}
 
@@ -211,8 +212,15 @@ bool rcuref_get_slowpath(rcuref_t *ref)
 	 * object memory, but prevents the obvious reference count overflow
 	 * damage.
 	 */
-	if (WARN_ONCE(cnt > RCUREF_MAXREF, "rcuref saturated - leaking memory"))
+	if (cnt > RCUREF_MAXREF) {
+		trace_printk("get(SATURATED): %px %pS\n", ref, __builtin_return_address(0));
+		WARN_ONCE(1, "rcuref saturated - leaking memory");
 		atomic_set(&ref->refcnt, RCUREF_SATURATED);
+	} else {
+		trace_printk("get(UNDEFINED): %px %pS\n", ref, __builtin_return_address(0));
+		WARN_ON_ONCE(1);
+	}
+
 	return true;
 }
 EXPORT_SYMBOL_GPL(rcuref_get_slowpath);
@@ -248,9 +256,12 @@ bool rcuref_put_slowpath(rcuref_t *ref)
 		 * require a retry. If this fails the caller is not
 		 * allowed to deconstruct the object.
 		 */
-		if (!atomic_try_cmpxchg_release(&ref->refcnt, &cnt, RCUREF_DEAD))
+		if (!atomic_try_cmpxchg_release(&ref->refcnt, &cnt, RCUREF_DEAD)) {
+			trace_printk("put(NOTDEAD): %px %pS\n", ref, __builtin_return_address(0));
 			return false;
+		}
 
+		trace_printk("put(NOWDEAD): %px %pS\n", ref, __builtin_return_address(0));
 		/*
 		 * The caller can safely schedule the object for
 		 * deconstruction. Provide acquire ordering.
@@ -264,7 +275,9 @@ bool rcuref_put_slowpath(rcuref_t *ref)
 	 * put() operation is imbalanced. Warn, put the reference count back to
 	 * DEAD and tell the caller to not deconstruct the object.
 	 */
-	if (WARN_ONCE(cnt >= RCUREF_RELEASED, "rcuref - imbalanced put()")) {
+	if (cnt >= RCUREF_RELEASED) {
+		trace_printk("put(WASDEAD): %px %pS\n", ref, __builtin_return_address(0));
+		WARN_ONCE(1, "rcuref - imbalanced put()");
 		atomic_set(&ref->refcnt, RCUREF_DEAD);
 		return false;
 	}
@@ -274,8 +287,13 @@ bool rcuref_put_slowpath(rcuref_t *ref)
 	 * mean saturation value and tell the caller to not deconstruct the
 	 * object.
 	 */
-	if (cnt > RCUREF_MAXREF)
+	if (cnt > RCUREF_MAXREF) {
+		trace_printk("put(SATURATED): %px %pS\n", ref, __builtin_return_address(0));
 		atomic_set(&ref->refcnt, RCUREF_SATURATED);
+	} else {
+		trace_printk("put(UNDEFINED): %px %pS\n", ref, __builtin_return_address(0));
+		WARN_ON_ONCE(1);
+	}
 	return false;
 }
 EXPORT_SYMBOL_GPL(rcuref_put_slowpath);


  reply	other threads:[~2023-12-12 18:16 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-15  4:05 Urgent Bug Report Kernel crash 6.5.2 Martin Zaharinov
2023-09-15  6:45 ` Eric Dumazet
2023-09-15 22:23   ` Martin Zaharinov
2023-11-16 14:17   ` Martin Zaharinov
2023-12-06 22:26     ` Martin Zaharinov
     [not found]       ` <5E63894D-913B-416C-B901-F628BB6C00E0@gmail.com>
2023-12-08 22:20         ` Thomas Gleixner
2023-12-08 23:01           ` Martin Zaharinov
2023-12-12 18:16             ` Thomas Gleixner [this message]
2023-12-19  9:25               ` Martin Zaharinov
2023-12-19 14:26                 ` Thomas Gleixner
2023-12-22 17:26                   ` Martin Zaharinov
2023-12-29 12:00                     ` Martin Zaharinov
2024-01-04 20:51                       ` Martin Zaharinov
2024-01-07 11:03                         ` Martin Zaharinov
2023-09-15 23:00 ` Martin Zaharinov
2023-09-15 23:11   ` Martin Zaharinov
2023-09-16  8:27     ` Paolo Abeni
     [not found]       ` <CALidq=UR=3rOHZczCnb1bEhbt9So60UZ5y60Cdh4aP41FkB5Tw@mail.gmail.com>
2023-09-17 11:35         ` Martin Zaharinov
2023-09-17 11:40         ` Martin Zaharinov
2023-09-17 11:55           ` Martin Zaharinov
2023-09-17 12:04             ` Holger Hoffstätte
2023-09-18  8:09             ` Eric Dumazet
2023-09-19 20:09             ` Martin Zaharinov
2023-09-20  3:59               ` Eric Dumazet
2023-09-20  6:05                 ` Martin Zaharinov
2023-09-20  6:16                   ` Bagas Sanjaya
2023-09-20  7:03                     ` Martin Zaharinov
2023-09-20  7:25                       ` Eric Dumazet
2023-09-20  7:29                         ` Eric Dumazet
2023-09-20  7:32                           ` Martin Zaharinov
2023-09-21  7:50                             ` Bagas Sanjaya
2023-09-21  8:13                               ` Martin Zaharinov
2023-09-22  3:06                                 ` Bagas Sanjaya
2023-09-22  9:50                                   ` Linux regression tracking (Thorsten Leemhuis)
2023-09-22 11:09                                     ` Bagas Sanjaya

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r0jrp9qi.ffs@tglx \
    --to=tglx@linutronix.de \
    --cc=dsahern@gmail.com \
    --cc=edumazet@google.com \
    --cc=kuba+netdrv@kernel.org \
    --cc=kuba@kernel.org \
    --cc=micron10@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=patchwork-bot+netdevbpf@kernel.org \
    --cc=peterz@infradead.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.