All of lore.kernel.org
 help / color / mirror / Atom feed
* [sudeep-holla:for-next/arm_fw/updates 2/2] drivers/firmware/arm/rmm/rmi.c:535 rmi_sro_donate_noncontig() error: buffer overflow 'sro->addr_list' 256 <= s32max
@ 2026-11-09 18:29 kernel test robot
  0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-11-09 18:29 UTC (permalink / raw)
  To: oe-kbuild; +Cc: lkp, Dan Carpenter

Unfiltered warning: this smatch report is sent as-is and has not been
reviewed for false positives, so please treat it with due skepticism.

BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
TO: Sudeep Holla <sudeep.holla@kernel.org>
CC: Yeoreum Yun <yeoreum.yun@arm.com>
CC: Suzuki K Poulose <suzuki.poulose@arm.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git for-next/arm_fw/updates
head:   49c49ca0c4d02848a9576f72c4741c38c5ba09de
commit: 49c49ca0c4d02848a9576f72c4741c38c5ba09de [2/2] firmware: arm: Group interface drivers under arm/
:::::: branch date: 7 hours ago
:::::: commit date: 7 hours ago
config: arm64-randconfig-2200-20261109 (https://download.01.org/0day-ci/archive/20261109/202611091947.OFBRJdT4-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 10.5.0
smatch: v0.5.0-9187-g5189e3fb

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202611091947.OFBRJdT4-lkp@intel.com/

smatch warnings:
drivers/firmware/arm/rmm/rmi.c:535 rmi_sro_donate_noncontig() error: buffer overflow 'sro->addr_list' 256 <= s32max
drivers/firmware/arm/rmm/rmi.c:535 rmi_sro_donate_noncontig() error: buffer overflow 'sro->addr_list' 256 <= s32max

vim +535 drivers/firmware/arm/rmm/rmi.c

bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  398  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  399  static int rmi_sro_donate_noncontig(struct rmi_sro_state *sro,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  400  				    unsigned long sro_handle,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  401  				    unsigned long donatereq,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  402  				    struct arm_smccc_1_2_regs *out_regs,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  403  				    gfp_t gfp)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  404  {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  405  	unsigned long block_size_fld = RMI_DONATE_BLOCK_SIZE(donatereq);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  406  	unsigned long block_size = rmi_addr_block_size_to_bytes(block_size_fld);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  407  	unsigned long count = RMI_DONATE_COUNT(donatereq);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  408  	unsigned long state = RMI_DONATE_STATE(donatereq);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  409  	unsigned long found = 0;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  410  	unsigned long donated_granules;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  411  	unsigned long granules_per_block = block_size >> PAGE_SHIFT;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  412  	unsigned long consumed_blocks;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  413  	int addr_list_start = sro->addr_count;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  414  	int ret, i, src;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  415  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  416  	/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  417  	 * We can't allocate blocks more than what the buddy allocator can
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  418  	 * satisfy. TODO: Add support for larger allocations.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  419  	 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  420  	if (get_order(block_size) > MAX_PAGE_ORDER)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  421  		return -ENOMEM;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  422  	/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  423  	 * Maximum value of RmiOpMemDonateReq:count is 2^(PAGE_SHIFT-2) - 1.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  424  	 * But we further clamp it down by the number of entries we can do
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  425  	 * in one go. The RMM can request  the remaining in the next iteration.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  426  	 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  427  	if (count > RMI_MAX_ADDR_LIST)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  428  		count = RMI_MAX_ADDR_LIST;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  429  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  430  	/* Gather the suitable entries to the end of the list */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  431  	i = 0;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  432  	while (i <  addr_list_start && found < count) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  433  		unsigned long entry = sro->addr_list[i];
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  434  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  435  		if (RMI_ADDR_RANGE_BLOCK_SIZE(entry) == block_size_fld &&
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  436  		    RMI_ADDR_RANGE_COUNT(entry) == 1 &&
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  437  		    RMI_ADDR_RANGE_STATE(entry) == state) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  438  			addr_list_start--;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  439  			swap(sro->addr_list[addr_list_start],
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  440  			     sro->addr_list[i]);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  441  			found++;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  442  			/* Continue from the swapped in entry */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  443  			continue;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  444  		}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  445  		/* Skip past the entry */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  446  		i++;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  447  	}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  448  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  449  	ret = rmi_sro_ensure_capacity(sro, count - found);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  450  	if (ret) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  451  		/* If we have found some entries, donate them and try again */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  452  		if (found)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  453  			goto mem_donate;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  454  		/* Otherwise free up the list and start again */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  455  		rmi_sro_free(sro);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  456  		/* Reset the addr_list_start to match sro->addr_count */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  457  		addr_list_start = 0;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  458  	}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  459  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  460  	for (; found < count; found++) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  461  		unsigned long addr_range;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  462  		void *virt = alloc_pages_exact(block_size, gfp);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  463  		phys_addr_t phys;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  464  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  465  		if (!virt)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  466  			return -ENOMEM;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  467  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  468  		phys = virt_to_phys(virt);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  469  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  470  		if (state == RMI_OP_MEM_DELEGATED) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  471  			phys_addr_t delegated_phys;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  472  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  473  			if (rmi_delegate_range(phys, block_size, &delegated_phys)) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  474  				if (!rmi_undelegate_range(phys, delegated_phys - phys))
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  475  					free_pages_exact(virt, block_size);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  476  				return -ENXIO;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  477  			}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  478  		}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  479  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  480  		addr_range = phys & RMI_ADDR_RANGE_ADDR_MASK;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  481  		FIELD_MODIFY(RMI_ADDR_RANGE_BLOCK_SIZE_MASK, &addr_range, block_size_fld);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  482  		FIELD_MODIFY(RMI_ADDR_RANGE_COUNT_MASK, &addr_range, 1);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  483  		FIELD_MODIFY(RMI_ADDR_RANGE_STATE_MASK, &addr_range, state);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  484  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  485  		sro->addr_list[sro->addr_count++] = addr_range;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  486  	}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  487  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  488  mem_donate:
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  489  	rmi_op_mem_donate(sro_handle,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  490  			  virt_to_phys(&sro->addr_list[addr_list_start]),
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  491  			  found, 0, out_regs);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  492  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  493  	donated_granules = out_regs->a1;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  494  	/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  495  	 * The RMM shouldn't report more granules than we provided, but clamp
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  496  	 * just in case.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  497  	 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  498  	if (WARN_ON_ONCE(donated_granules > found * granules_per_block))
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  499  		donated_granules = found * granules_per_block;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  500  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  501  	/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  502  	 * The RMM reports the consumed memory in terms of granules, but we
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  503  	 * track in the address lists in block-sized ranges. So divide to get
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  504  	 * the number of (complete) consumed blocks.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  505  	 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  506  	consumed_blocks = donated_granules / granules_per_block;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  507  	if (donated_granules % granules_per_block) {
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  508  		/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  509  		 * A block has been partially consumed, the start is owned by
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  510  		 * the RMM, the tail is owned by the host
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  511  		 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  512  		unsigned long entry =
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  513  			sro->addr_list[addr_list_start + consumed_blocks];
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  514  		unsigned long donated_size =
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  515  			(donated_granules % granules_per_block) << PAGE_SHIFT;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  516  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  517  		free_addr_range(entry, donated_size);
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  518  		/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  519  		 * This block is now fully 'consumed' (either held by the RMM or
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  520  		 * freed)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  521  		 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  522  		consumed_blocks++;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  523  	}
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  524  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  525  	/*
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  526  	 * Keep just the blocks the RMM didn't use in addr_list
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  527  	 * RMM claimed consumed_blocks entries from addr_list_start.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  528  	 * Move the entries left out at the end i.e.,
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  529  	 * [ addr_list_start + consumed_blocks, addr_list_start + found)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  530  	 * to the rest of the valid entries and adjust the addr_count to
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  531  	 * reflect the available entries.
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  532  	 */
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  533  	for (i = 0, src = addr_list_start + consumed_blocks;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  534  		i < found - consumed_blocks; i++)
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02 @535  		sro->addr_list[addr_list_start + i] = sro->addr_list[src + i];
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  536  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  537  	sro->addr_count -= consumed_blocks;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  538  
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  539  	return 0;
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  540  }
bc1360cabe27388 drivers/firmware/arm_rmm/rmi.c Steven Price 2026-10-02  541  

:::::: The code at line 535 was first introduced by commit
:::::: bc1360cabe273886c502d8b6b2da7f05474cb923 firmware: arm_rmm: Add support for SRO

:::::: TO: Steven Price <steven.price@arm.com>
:::::: CC: Catalin Marinas <catalin.marinas@arm.com>

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-09 18:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 18:29 [sudeep-holla:for-next/arm_fw/updates 2/2] drivers/firmware/arm/rmm/rmi.c:535 rmi_sro_donate_noncontig() error: buffer overflow 'sro->addr_list' 256 <= s32max kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.