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