On 08.11.24 15:38, David Laight wrote:
From: Peter Kaestle
Sent: 08 November 2024 14:02
The following commit broke dumping unsigned on big endian:
34751d8bf (libbb/dump: correct handling of 1-byte signed int format, 2023-05-26)
Example of the bug:
root@fct:~ >echo -ne "\xfe\xfd\xfc\xfb" > /tmp/testfile
before 34751d8bf:
$>/tmp/busybox_1_36_1 hexdump /tmp/testfile
0000000 fefd fcfb
0000004
with 34751d8bf:
$>busybox_1_37_0 hexdump /tmp/testfile
0000000 fefd00fe fcfb00fc
0000004
Problem originated from loading data into 32-bit "value" variable and
then doing the memcpy of 2 or 4 bytes into value afterwards, without
taking care of the byte order in case of big-endian cpus.
Replicating same solution used in F_INT with the union fixes the issue.
I'd suggest getting rid of move_from_unaligned16/32() and replacing
with something that just returns the value.
Then the clauses are just:
case 2:
value = read_unaligned_u16(bp);
break;
and nothing will go wrong.
Good idea, but unfortunately after "git grepping" busybox repo, it seems
these kind of functions are not defined anywhere.
All I can find is those "move_from_unaligned*" functions defined inside
include/platform.h. And some "get_unaligned_be32/get_unaligned_le32",
which are obviously not endian-safe.
Could you please help me understand, where you think those functions
should come from?
But the fact, that Denys originally introduced those
"move_from_unaligned" calls at this place with 34751d8bf (libbb/dump:
correct handling of 1-byte signed int format, 2023-05-26) is an
indication to me, that this is the right way to do it.
He probably just overlooked the issue with big-endian, described in my
original post.
best regards,
--peter;
The code will be much smaller as well.
on x86 the above is just *(unsigned short *)bp rather than something
that (I suspect) call memcpy().
David
Signed-off-by: Peter Kaestle <[email protected]>
---
libbb/dump.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/libbb/dump.c b/libbb/dump.c
index b406a2428..87180dff5 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -665,15 +665,23 @@ static NOINLINE void display(priv_dumper_t* dumper)
conv_u(pr, bp);
break;
case F_UINT: {
+ union {
+ uint16_t val16;
+ uint32_t val32;
+ uint64_t val64;
+ } u;
unsigned value =
(unsigned char)*bp;
+
switch (pr->bcnt) {
case 1:
break;
case 2:
-
move_from_unaligned16(value, bp);
+
move_from_unaligned16(u.val16, bp);
+ value = u.val16;
break;
case 4:
-
move_from_unaligned32(value, bp);
+
move_from_unaligned32(u.val32, bp);
+ value = u.val32;
break;
/* case 8: no users yet
*/
}
--
2.35.7
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT,
UK
Registration No: 1397386 (Wales)
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox