[PATCH v2 2/6] misc: Add support for bit fields in NVMEM cells

Aswin Murugan aswin.murugan at oss.qualcomm.com
Thu Feb 19 12:24:06 CET 2026


Hi Sean,

On 2/18/2026 7:37 AM, Sean Anderson wrote:
> On 2/17/26 14:05, Aswin Murugan wrote:
>> Hi Sean,
>>
>> Thanks for your feedback.
>> To address stack smashing, which occurs when the cell size is larger 
>> than 4 bytes, I will revert the `nvmem_cell_read()` call in 
>> `reboot_mode_get()` to pass `sizeof(*mode)` as the size, consistent 
>> with the original implementation.
>>
>> Inside `nvmem_cell_read()`, will modify the validation check. Instead 
>> of enforcing `size == cell->size`, will check if `cell->size` is 
>> within the passed `size` (i.e., `cell->size <= size`) to correctly 
>> support our 1-byte read case where the buffer is 4 bytes.
>
> Then don't we need to zero out the rest of the buffer?
>
> I would expect the check to be
>
> if ((cell->bit_offset && size > cell->size) || size != cell->size)
>     return -EINVAL;
>
>> Also, i2c_eeprom_read() and misc_read() will continue to request a 
>> read for cell->size instead of the passed buffer size, ensuring we 
>> only read the valid data from the hardware.
>>
>> Regarding the bit field logic, as you suggested will simplify the 
>> bit‑field handling to max u32 size, which significantly reduces the 
>> code complexity. Given this simplification, is it still necessary to 
>> keep this bit‑manipulation logic behind a separate config option?
>
> I think it's likely. You can check the growth with 
> scripts/bloat-o-meter in
> Linux. Since this is mainly for U-Boot proper I'd say a couple hundred 
> bytes
> is reasonable for this feature.
>
>> Kindly confirm if this approach aligns with your expectations. 
>
> Please remember to reply on the bottom :)
>
> --Sean

The suggested check will fail for our case, we always pass size = 
sizeof(u32) = 4 bytes regardless of the actual cell size.

Example: 1-byte cell with 7-bit field

cell->size = 1, bit_offset = 1, nbits = 7, size = 4

With suggested check: if ((cell->bit_offset && size > cell->size) || 
size != cell->size) -> (1 && 4 > 1) || 4 != 1 -> TRUE -> rejects valid case

If we have a check as below:

if (size < cell->size) -> 4 < 1 -> FALSE -> correctly allows

Then if cell has nbits set, bit field bounds can be validated separately 
as follows:

bytes_needed = DIV_ROUND_UP(7+1, 8)

if (bytes_needed > cell->size || bytes_needed > sizeof(u32) || size != 
sizeof(u32))

This validates:

  * bytes_needed > cell->size: Bit field doesn't exceed actual cell size
  * bytes_needed > sizeof(u32): Bit field doesn't exceed maximum
    supported size
  * size != sizeof(u32): Buffer size is correct for bit field operations

Thanks

Aswin





More information about the U-Boot mailing list