From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0302F3314D0 for ; Sat, 15 Aug 2026 18:13:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786817624; cv=none; b=R/06KTQLUXSA8d4VBm3l1CHkeq6PmMHKoUmDVUYrKqZWEfxA3k/dwsV4fSf/KVgQ5QOO7eI3o6ixOGtFra3Ze0apaaM+rSw6973fQriZzeCnWlR7eueDV+L9UKfuAA/srltM2bALnGeCluDmOyWU1cJlOZSwBI4SXuxI7raw8ds= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786817624; c=relaxed/simple; bh=96dNgm0w4p4mneCX3nrwNYF339ix1yCXiaxbeFg7LcM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FIXU4OWqwEbAzr7Vq8/C4IhQxi68Vb0wq6yV+0RKkENasHXzwd06gpvxbeMthtxok2X5DUwmF23+8JWWcU61VPD9x+VBsYwW+zaQOFP2JlKRQrUlZIsa8P4rC0NMaPxuYELsSOW5wz34DVEcKrIqys0IqNd7bv7ex3zFa7tYEww= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=E5Dm7D1n; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="E5Dm7D1n" Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-3810c5d691bso1531212a91.1 for ; Sat, 15 Aug 2026 11:13:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786817618; x=1787422418; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=V91oZrI/zJYRrYjWs8UIHznDrCj9rfvAd4MAMUD9J1o=; b=E5Dm7D1nARdS9er69ZSJ4AAyLGbJn9O7qLI/uWJbMzmtQI65ZO4b9ZCZEt5QIxM3Yu pBlz7zT6eJQlthO7zulBqLLIS2YE6CAonHY3Q/VKHHjZXOfbhpYwJ0JjueAREWLhkayO jgIOFD6Uj49c2A3igYNX6lBIHruwCo8EdtcJD7zIKeioIp4Mv8UmRS1vW9zV5CROUOE0 /hhjzN5SYqY7xgaTgx3qlZPFPVSSle2Up/JjBKd0nPbo+/8ruPsSUpmmsLMvr9fK1ZzX DFoeRrWQsZzKY4HOwvo11MH1igz5KCe3BnvoPMmPLykop1BFeLVbcIv62rfzULxVsLBi 6wjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786817618; x=1787422418; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=V91oZrI/zJYRrYjWs8UIHznDrCj9rfvAd4MAMUD9J1o=; b=WSR3NCTrUJTzHj7jqvXckps7xPdRM0SedpHQTRBMX5P/soeaCuEdBBEu3NZW7p9bsf 6JiSPCM92X+1rPHRS1L0CmmJ/86JG08d7fsvXlPLfA6EjMGpKiS3CqR8wLKXgIa+VOfu pDRUIjVNPV8ePopwddL4RcvYhse57voq38CGsgjGNmWboQlEHh5J3b6gJoyfDP0Q6x1b yRfFEWw19LiaTfDhpY7FztfRvZH8j9bAhWiOWlrTNeqXoQvpcWEmsg3zVU3TQDp0tmCq +EkfYu+Jw0O7xYNnOpEgjBqeybxFfJl9hZMfWa9yXvDroflF4LvO7hrauWjDttU6VkEa p8RA== X-Forwarded-Encrypted: i=1; AHgh+RrytGdoaRRrAtoG8CCHd0ojOr+vjElomeXx+aPM0QwhjyDJcNboNyEkCK1eaIQSwYtexBamgpYVJt83drw=@vger.kernel.org X-Gm-Message-State: AOJu0YxDjARhRHcrJRQr9a/B3NxR6gf/xNpD8z7R/Sve+mReLul4YbAP oLhF2e1pRHUenQjvh1zetMfky9rY49SuP1ZwvW+aqD3Ws+yZYEQ0pFcJ X-Gm-Gg: AR+sD11rYwZgA0zYPIZMg1sCdCDAzrdmcT1Qv8hIxOCVTJ2/bFeddjL9iuPCRBUMdz4 96PwyMd5Mo7R/dEOozsmggl8PfRvOh96SG8eTnmBNSjdnnq9viTwr68kuv7rjqMhZbUVsOeKTAV 7mT2VbOWwqathh2gAInLfaSTIHXq4uB/JJUJm6cO0HTXS3Vto0z3/cNd23GD+MCMvYvNKhvTpTw +Zmnmz84k0kWZEusA9Vv8kNgTwXz2qkCSo2ZYi3dnjxRnb+Ru11hEKdzFVDK/1J6/4qO3dI4uRT dYlif5TMLUpfu52ojKD62zaly1FR8GOM2XuTGrQO4XUgscnNJQbEOBv/qgmxlYbEW35JR5shLfk 7u/i9EcCF1JSGazvVk4lvH1EkUkN923HjHnhLUak/i32CAJ4Xt8qHihUlqEp/fSYZuyKJtXerce bBmM+9p1lC5V5tPY61FBubeSSoe+S0ozn/R0mELP468mWHauvgHfK+/WIvVjXXJLg/z9RkyjIRL dJBcn6SGEd6OrLiCWiIXDjg5KU= X-Received: by 2002:a17:90b:1b05:b0:380:873:49cb with SMTP id 98e67ed59e1d1-3933baa0d6amr14788639a91.21.1786817618461; Sat, 15 Aug 2026 11:13:38 -0700 (PDT) Received: from localhost.localdomain ([240a:4280:4800:6ace:25e8:2607:e94d:caaf]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-394eb7539d3sm7304254a91.15.2026.08.15.11.13.30 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sat, 15 Aug 2026 11:13:36 -0700 (PDT) From: Liu Zhenlong To: andi.shyti@kernel.org, chris.packham@alliedtelesis.co.nz, jochen@scram.de, maddy@linux.ibm.com, vz@mleia.com, piotr.wojtaszczyk@timesys.com Cc: mpe@ellerman.id.uk, npiggin@gmail.com, chleroy@kernel.org, grant.likely@secretlab.ca, neelegup@linux.vnet.ibm.com, benh@kernel.crashing.org, wsa@kernel.org, stigge@antcom.de, linux-i2c@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Liu Zhenlong , stable@vger.kernel.org Subject: [PATCH 5/5] i2c: pnx: fix device_node refcount leak in i2c_pnx_probe()/i2c_pnx_remove() Date: Sun, 16 Aug 2026 02:12:04 +0800 Message-ID: <20260815181204.2321-6-dragonliu2018@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260815181204.2321-1-dragonliu2018@gmail.com> References: <20260815181204.2321-1-dragonliu2018@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit i2c_pnx_probe() calls of_node_get() to take an extra reference on the platform device's of_node when assigning it to the adapter device, but none of the probe error paths nor i2c_pnx_remove() drops it. device_release() does not call of_node_put() and i2c_adapter_dev_release() only completes a struct, so the extra reference is never released, leaking the device_node on every probe failure and every adapter removal. Add the matching of_node_put() to all probe error paths (the three early return paths before clk_prepare_enable(), and the out_clock label which covers the wait_reset(), platform_get_irq(), devm_request_irq() and i2c_add_numbered_adapter() failure paths; dev is devm_kzalloc'ed so adapter.dev.of_node is NULL and of_node_put() is a no-op when CONFIG_OF is not set) and to i2c_pnx_remove(). In i2c_pnx_remove(), i2c_del_adapter() clears adap->dev with memset() at the end (commit bd4bc3dbded9 ("i2c: Clear i2c_adapter.dev on adapter removal")), which zeroes adap->dev.of_node before of_node_put() runs. Cache the pointer before calling i2c_del_adapter(), the same approach used in i2c-mux (i2c_mux_del_adapters) and mtd (commit 56570bdad5e3 ("mtd: core: Fix refcount error in del_mtd_device()")). Compile-tested with gcc on arm64 defconfig using COMPILE_TEST; no hardware available for runtime testing. Fixes: b41a216dafe4 ("i2c: Add device tree support to i2c-pnx.c") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Liu Zhenlong --- drivers/i2c/busses/i2c-pnx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 8daa0008bd05..0b6c144d9a21 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -644,20 +644,26 @@ static int i2c_pnx_probe(struct platform_device *pdev) } #endif alg_data->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(alg_data->clk)) + if (IS_ERR(alg_data->clk)) { + of_node_put(alg_data->adapter.dev.of_node); return PTR_ERR(alg_data->clk); + } snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name), "%s", pdev->name); /* Register I/O resource */ alg_data->ioaddr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(alg_data->ioaddr)) + if (IS_ERR(alg_data->ioaddr)) { + of_node_put(alg_data->adapter.dev.of_node); return PTR_ERR(alg_data->ioaddr); + } ret = clk_prepare_enable(alg_data->clk); - if (ret) + if (ret) { + of_node_put(alg_data->adapter.dev.of_node); return ret; + } freq = clk_get_rate(alg_data->clk); @@ -707,14 +713,17 @@ static int i2c_pnx_probe(struct platform_device *pdev) out_clock: clk_disable_unprepare(alg_data->clk); + of_node_put(alg_data->adapter.dev.of_node); return ret; } static void i2c_pnx_remove(struct platform_device *pdev) { struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); + struct device_node *node = alg_data->adapter.dev.of_node; i2c_del_adapter(&alg_data->adapter); + of_node_put(node); clk_disable_unprepare(alg_data->clk); } -- 2.55.0