From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 405D8C46467 for ; Sun, 18 Dec 2022 17:06:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233412AbiLRRG0 (ORCPT ); Sun, 18 Dec 2022 12:06:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233363AbiLRRF1 (ORCPT ); Sun, 18 Dec 2022 12:05:27 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37618BF5E; Sun, 18 Dec 2022 08:21:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C868960DCC; Sun, 18 Dec 2022 16:21:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E5B4C433EF; Sun, 18 Dec 2022 16:21:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1671380518; bh=aTjcHvXyQs/tqs+Mrj/cng7jBZ/gFHXuLjqMVQaO7+E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Rh9kOq6HgqZqNi0+gnTjgQpYaxQrLRhUF/geJuJspN6hI+JtCeQA/jcujK1DBpO/Q MLYjR5CCNSbhH68pMoVuAM6DuYv7/sYqAPdeVvPCD/pMOOnSQk83pZEaWkKmvTVd+r fxWC7G6YV2T8/LkILys12eFDszRldSVzGYXzvbgFCYQP+/kjt8nE1Z5IeuKwRZwo2s 3t5Xay0s9G4wVjVQS1kwZFGLTU/zfGlhe6zQ2E+BQ/b6FEddG+D/h422PjFo2CyDse +hLRVxj8qsLHTsB9SbQOkfIcvNcguK+U5jOK2+Kpa7ftOQXypfIVjYCk6I61UlAO0R D3p5nAuH6Gi5g== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Zhang Yuchen , Corey Minyard , Sasha Levin , openipmi-developer@lists.sourceforge.net Subject: [PATCH AUTOSEL 4.14 04/23] ipmi: fix memleak when unload ipmi driver Date: Sun, 18 Dec 2022 11:21:30 -0500 Message-Id: <20221218162149.935047-4-sashal@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221218162149.935047-1-sashal@kernel.org> References: <20221218162149.935047-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Zhang Yuchen [ Upstream commit 36992eb6b9b83f7f9cdc8e74fb5799d7b52e83e9 ] After the IPMI disconnect problem, the memory kept rising and we tried to unload the driver to free the memory. However, only part of the free memory is recovered after the driver is uninstalled. Using ebpf to hook free functions, we find that neither ipmi_user nor ipmi_smi_msg is free, only ipmi_recv_msg is free. We find that the deliver_smi_err_response call in clean_smi_msgs does the destroy processing on each message from the xmit_msg queue without checking the return value and free ipmi_smi_msg. deliver_smi_err_response is called only at this location. Adding the free handling has no effect. To verify, try using ebpf to trace the free function. $ bpftrace -e 'kretprobe:ipmi_alloc_recv_msg {printf("alloc rcv %p\n",retval);} kprobe:free_recv_msg {printf("free recv %p\n", arg0)} kretprobe:ipmi_alloc_smi_msg {printf("alloc smi %p\n", retval);} kprobe:free_smi_msg {printf("free smi %p\n",arg0)}' Signed-off-by: Zhang Yuchen Message-Id: <20221007092617.87597-4-zhangyuchen.lcr@bytedance.com> [Fixed the comment above handle_one_recv_msg().] Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_msghandler.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index f72a272eeb9b..de03c5c07896 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2931,12 +2931,16 @@ static void deliver_smi_err_response(ipmi_smi_t intf, struct ipmi_smi_msg *msg, unsigned char err) { + int rv; msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; msg->rsp[2] = err; msg->rsp_size = 3; - /* It's an error, so it will never requeue, no need to check return. */ - handle_one_recv_msg(intf, msg); + + /* This will never requeue, but it may ask us to free the message. */ + rv = handle_one_recv_msg(intf, msg); + if (rv == 0) + ipmi_free_smi_msg(msg); } static void cleanup_smi_msgs(ipmi_smi_t intf) -- 2.35.1