diff options
author | Marek BehĂșn <marek.behun@nic.cz> | 2021-05-20 13:23:50 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-05-24 14:21:30 -0400 |
commit | 364bef150d9f2a03aebb427363031d56b244bf84 (patch) | |
tree | ba8e203cb126f31fc7fb0e5f2f1d62020f68d0ca /board/samsung | |
parent | 2177f924bf585d083fdbb3c1ff1479794ee8ccac (diff) | |
download | u-boot-364bef150d9f2a03aebb427363031d56b244bf84.zip u-boot-364bef150d9f2a03aebb427363031d56b244bf84.tar.gz u-boot-364bef150d9f2a03aebb427363031d56b244bf84.tar.bz2 |
regmap: fix a serious pointer casting bug
There is a serious bug in regmap_read() and regmap_write() functions
where an uint pointer is cast to (void *) which is then cast to (u8 *),
(u16 *), (u32 *) or (u64 *), depending on register width of the map.
For example given a regmap with 16-bit register width the code
int val = 0x12340000;
regmap_read(map, 0, &val);
only changes the lower 16 bits of val on little-endian machines.
The upper 16 bits will remain 0x1234.
Nobody noticed this probably because this bug can be triggered with
regmap_write() only on big-endian architectures (which are not used by
many people anymore), and on little endian this bug has consequences
only if register width is 8 or 16 bits and also the memory place to
which regmap_read() should store it's result has non-zero upper bits,
which it seems doesn't happen anywhere in U-Boot normally. CI managed to
trigger this bug in unit test of dm_test_devm_regmap_field when compiled
for sandbox_defconfig using LTO.
Fix this by utilizing an union { u8; u16; u32; u64; } and reading data
into this union / writing data from this union.
Signed-off-by: Marek BehĂșn <marek.behun@nic.cz>
Cc: Simon Glass <sjg@chromium.org>
Cc: Heiko Schocher <hs@denx.de>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Pratyush Yadav <p.yadav@ti.com>
Diffstat (limited to 'board/samsung')
0 files changed, 0 insertions, 0 deletions