From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 938761FBEA6; Sat, 12 Sep 2026 16:33:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789230784; cv=none; b=CoWtx8efv7EHLBv8lhCKBMd2hE5+hFW7L1bKrzxwLH7mObirjt9YQoqo+P2Y2pMJfM/g4mmOxo31BpLxNNYDDi1qjFcfvpwcCvgo9H/Sqt1ezVKbZLRh/7drs1iZxh9Ra/N4CgpUQmATtEVosWgnkGXn3OkUOMSqXrijZ79glBk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789230784; c=relaxed/simple; bh=sCr4F2XL9IHHE5Z1nbMsE95IljXGdkyYLRbFFO0gOQE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cmwimAc3ISzp9r9Mk2jPRGe7iKdVs0b+srRDnKWslHCOjinVkea38sg0HFKmgrf30LUvXaf75a6TA+9xEEarS+TpPP1TOldQ0sNPT1ey6eMO1UEKO4nmxYICKXRayj898NrVMcwxEtHd5TxigGERPWHJnzdE4CjHIlXZZBdyz7s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=AsH1cWP1; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="AsH1cWP1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B154E1F000FF; Sat, 12 Sep 2026 16:33:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789230783; bh=VvZZZEzaLXCD/qXSSBXoWtd/ymezhA+ZhOXYlik0U3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AsH1cWP1/No1meVeY81V7e81KY71r/K3bUMpeA7A5nmt3CuAIVaETGhlNi1XjfkVv KoSb97Ax/179x53bb9lepdZ8eCMI8Ek+dEtwn2zc7VXXSoj8DnlsYV0dSsyip1XPMO v8odqtFKD993YLIUwYU+PA3qk09szelmo/xIYY1k= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Mukesh Ojha , Sasha Levin Subject: [PATCH 6.1 0864/1191] remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() Date: Sat, 12 Sep 2026 08:59:52 +0200 Message-ID: <20260912065607.659099601@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065548.086904252@linuxfoundation.org> References: <20260912065548.086904252@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mukesh Ojha [ Upstream commit 49abb5d6e1ac8169cdfc0c3aa4408e0d90ee5696 ] Replace the open-coded resource table iteration loop in rproc_handle_resources() with the rsc_table_for_each_entry() helper. The remoteproc-specific dispatch logic (vendor resource handling via rproc_handle_rsc(), RSC_LAST bounds check, handler table lookup) is moved into a local callback rproc_handle_rsc_entry(), keeping the iteration mechanics in one canonical place. The callback receives the payload offset within the table so that handlers which write back into the resource table (e.g. rproc_handle_carveout() recording a dynamically allocated address via rsc_offset) continue to work correctly. No functional change. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20260506050107.1985033-3-mukesh.ojha@oss.qualcomm.com Stable-dep-of: bb840ea69347 ("remoteproc: fix OOB read via signed offset in rsc_table_for_each_entry()") Signed-off-by: Sasha Levin --- drivers/remoteproc/remoteproc_core.c | 81 +++++++++++++--------------- include/linux/rsc_table.h | 53 ++++++++++++++++++ 2 files changed, 91 insertions(+), 43 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index f1a7cc2744f5f..fc92de3cc0de2 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1014,60 +1014,55 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = { [RSC_VDEV] = rproc_handle_vdev, }; -/* handle firmware resource entries before booting the remote processor */ -static int rproc_handle_resources(struct rproc *rproc, - rproc_handle_resource_t handlers[RSC_LAST]) +struct rproc_rsc_cb_data { + struct rproc *rproc; + rproc_handle_resource_t *handlers; +}; + +static int rproc_handle_rsc_entry(u32 type, void *rsc, int offset, + int avail, void *data) { + struct rproc_rsc_cb_data *d = data; + struct rproc *rproc = d->rproc; struct device *dev = &rproc->dev; rproc_handle_resource_t handler; - int ret = 0, i; - - if (!rproc->table_ptr) - return 0; + int ret; - for (i = 0; i < rproc->table_ptr->num; i++) { - int offset = rproc->table_ptr->offset[i]; - struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset; - int avail = rproc->table_sz - offset - sizeof(*hdr); - void *rsc = (void *)hdr + sizeof(*hdr); + dev_dbg(dev, "rsc: type %d\n", type); - /* make sure table isn't truncated */ - if (avail < 0) { - dev_err(dev, "rsc table is truncated\n"); - return -EINVAL; - } - - dev_dbg(dev, "rsc: type %d\n", hdr->type); + if (type >= RSC_VENDOR_START && type <= RSC_VENDOR_END) { + ret = rproc_handle_rsc(rproc, type, rsc, offset, avail); + if (ret == RSC_HANDLED) + return 0; + if (ret < 0) + return ret; + dev_warn(dev, "unsupported vendor resource %d\n", type); + return 0; + } - if (hdr->type >= RSC_VENDOR_START && - hdr->type <= RSC_VENDOR_END) { - ret = rproc_handle_rsc(rproc, hdr->type, rsc, - offset + sizeof(*hdr), avail); - if (ret == RSC_HANDLED) - continue; - else if (ret < 0) - break; + if (type >= RSC_LAST) { + dev_warn(dev, "unsupported resource %d\n", type); + return 0; + } - dev_warn(dev, "unsupported vendor resource %d\n", - hdr->type); - continue; - } + handler = d->handlers[type]; + if (!handler) + return 0; - if (hdr->type >= RSC_LAST) { - dev_warn(dev, "unsupported resource %d\n", hdr->type); - continue; - } + return handler(rproc, rsc, offset, avail); +} - handler = handlers[hdr->type]; - if (!handler) - continue; +/* handle firmware resource entries before booting the remote processor */ +static int rproc_handle_resources(struct rproc *rproc, + rproc_handle_resource_t handlers[RSC_LAST]) +{ + struct rproc_rsc_cb_data d = { .rproc = rproc, .handlers = handlers }; - ret = handler(rproc, rsc, offset + sizeof(*hdr), avail); - if (ret) - break; - } + if (!rproc->table_ptr) + return 0; - return ret; + return rsc_table_for_each_entry(rproc->table_ptr, rproc->table_sz, + &rproc->dev, rproc_handle_rsc_entry, &d); } static int rproc_prepare_subdevices(struct rproc *rproc) diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h index c32c8b6cd2a77..c6d6d553d8f11 100644 --- a/include/linux/rsc_table.h +++ b/include/linux/rsc_table.h @@ -303,4 +303,57 @@ struct fw_rsc_vdev { struct fw_rsc_vdev_vring vring[]; } __packed; +/** + * rsc_table_for_each_entry() - iterate over all entries in a resource table + * @table: pointer to the resource table + * @table_sz: total size of the table buffer in bytes + * @dev: device used for error logging + * @cb: callback invoked for each entry: + * @type - value from enum fw_resource_type + * @rsc - pointer to the entry payload (past struct fw_rsc_hdr) + * @offset - byte offset of the payload within the table; callers + * that write back into the table (e.g. to record a + * dynamically allocated address) use this to locate the + * entry for later update + * @avail - bytes available in the payload + * @data - caller-supplied private pointer + * Return 0 to continue iteration, non-zero to stop. + * @data: private pointer forwarded to @cb on every call + * + * Iterates over every resource entry in @table, performing the standard + * truncation check, and invokes @cb for each one. Iteration stops on the + * first non-zero return from @cb or on a malformed table. + * + * Returns 0 after a complete iteration, -EINVAL if the table is truncated, + * or the first non-zero value returned by @cb. + */ +static inline int rsc_table_for_each_entry(struct resource_table *table, + size_t table_sz, + struct device *dev, + int (*cb)(u32 type, void *rsc, + int offset, int avail, + void *data), + void *data) { + int i, ret; + + for (i = 0; i < table->num; i++) { + int offset = table->offset[i]; + struct fw_rsc_hdr *hdr = (void *)table + offset; + int avail = table_sz - offset - sizeof(*hdr); + int rsc_offset = offset + sizeof(*hdr); + void *rsc = (void *)hdr + sizeof(*hdr); + + if (avail < 0) { + dev_err(dev, "rsc table is truncated\n"); + return -EINVAL; + } + + ret = cb(hdr->type, rsc, rsc_offset, avail, data); + if (ret) + return ret; + } + + return 0; +} + #endif /* RSC_TABLE_H */ -- 2.53.0