Re: [PATCH v3 5/5] remoteproc: fix OOB read via signed offset in rsc_table_for_each_entry()

Bjorn Andersson <[email protected]>
Newsgroups org.kernel.vger.linux-remoteproc,org.kernel.vger.linux-kernel
Message-ID <anJjeJQcf18MgKRg@baldur>
On Mon, Aug 03, 2026 at 05:13:31PM +0530, Mukesh Ojha wrote:
> table->offset[i] is a u32 from firmware, but was stored into a signed
> int.  A crafted offset like 0xFFFFFFF0 becomes -16, placing hdr 16 bytes
> before the table buffer.  The subsequent avail check was bypassed
> because the negative int was promoted to a large size_t in the
> expression "table_sz - offset - sizeof(*hdr)", yielding a large positive
> avail and letting the out-of-bounds hdr->type read proceed undetected.
> 
> Store the offset as u32 and validate it with unsigned comparisons before
> any pointer arithmetic.
> 

Fixes: fd2c15ec1dd3 ("remoteproc: resource table overhaul")

Regards,
Bjorn

> Signed-off-by: Mukesh Ojha <[email protected]>
> ---
>  include/linux/rsc_table.h | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
> index 0ad9122c22af..71b60125310e 100644
> --- a/include/linux/rsc_table.h
> +++ b/include/linux/rsc_table.h
> @@ -310,17 +310,22 @@ static inline int rsc_table_for_each_entry(struct resource_table *table,
>  	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);
> +		u32 offset = table->offset[i];
> +		struct fw_rsc_hdr *hdr;
> +		int avail, rsc_offset;
> +		void *rsc;
>  
> -		if (avail < 0) {
> +		if (offset < sizeof(*table) || offset >= table_sz ||
> +		    table_sz - offset < sizeof(*hdr)) {
>  			dev_err(dev, "rsc table is truncated\n");
>  			return -EINVAL;
>  		}
>  
> +		hdr = (void *)table + offset;
> +		avail = table_sz - offset - sizeof(*hdr);
> +		rsc_offset = offset + sizeof(*hdr);
> +		rsc = (void *)hdr + sizeof(*hdr);
> +
>  		ret = cb(hdr->type, rsc, rsc_offset, avail, data);
>  		if (ret)
>  			return ret;
> -- 
> 2.53.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.