summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2025-10-16 13:49:17 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-19 16:34:04 +0200
commit04610b77809f6d579e8b90561027fa683755c331 (patch)
tree6e8bbdf668d3fde4c19a67047f6d2ea44a221268
parent53d6e403affbf6df2c859a0ea00ccfc1e72090ca (diff)
downloadlinux-04610b77809f6d579e8b90561027fa683755c331.tar.gz
linux-04610b77809f6d579e8b90561027fa683755c331.tar.bz2
linux-04610b77809f6d579e8b90561027fa683755c331.zip
ipmi: Fix handling of messages with provided receive message pointer
commit e2c69490dda5d4c9f1bfbb2898989c8f3530e354 upstream Prior to commit b52da4054ee0 ("ipmi: Rework user message limit handling"), i_ipmi_request() used to increase the user reference counter if the receive message is provided by the caller of IPMI API functions. This is no longer the case. However, ipmi_free_recv_msg() is still called and decreases the reference counter. This results in the reference counter reaching zero, the user data pointer is released, and all kinds of interesting crashes are seen. Fix the problem by increasing user reference counter if the receive message has been provided by the caller. Fixes: b52da4054ee0 ("ipmi: Rework user message limit handling") Reported-by: Eric Dumazet <edumazet@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Greg Thelen <gthelen@google.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-ID: <20251006201857.3433837-1-linux@roeck-us.net> Signed-off-by: Corey Minyard <corey@minyard.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 6fb8210879bb..99fe01321971 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2311,8 +2311,11 @@ static int i_ipmi_request(struct ipmi_user *user,
if (supplied_recv) {
recv_msg = supplied_recv;
recv_msg->user = user;
- if (user)
+ if (user) {
atomic_inc(&user->nr_msgs);
+ /* The put happens when the message is freed. */
+ kref_get(&user->refcount);
+ }
} else {
recv_msg = ipmi_alloc_recv_msg(user);
if (IS_ERR(recv_msg))