Expressions like u64 = u32 * u32 are unsafe because their products are
truncated to u32 even if left hand side is u64. This patch fixes all
problems like that one in fbutil.
To get right result not only left hand side have to be u64 but it's also
necessary to cast at least one of the operands of all leaf operators of
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
u64 = (u64)u32 * u32 + (u64)u32 * u32.
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
not overflow grub_uint64_t.
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
This patch also adds a comment to grub_video_fb_get_video_ptr() which
says it's arguments must be valid and no sanity check is performed
(like its siblings in grub-core/video/fb/fbutil.c).
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Since commit 7ce3259f67ac (video/fb/fbfill: Fix potential integer
overflow), clang builds of grub-emu have failed with messages like:
/usr/bin/ld: libgrubmods.a(libgrubmods_a-fbfill.o): in function `grub_video_fbfill_direct24':
fbfill.c:(.text+0x28e): undefined reference to `__muloti4'
This appears to be due to a weird quirk in how clang compiles
grub_mul(dst->mode_info->bytes_per_pixel, width, &rowskip)
which is grub_mul(unsigned int, int, &grub_size_t).
It looks like clang somewhere promotes everything to 128-bit maths
before ultimately reducing down to 64 bit for grub_size_t. I think
this is because width is signed, and indeed converting width to an
unsigned int makes the problem go away.
This conversion also makes more sense generally:
- the caller of all the fbfill_directN functions is
grub_video_fb_fill_dispatch() and it takes width and height as
unsigned ints already,
- it doesn't make sense to fill a negative width or height.
Convert the width and height arguments and associated loop counters
to unsigned ints.
Fixes: 7ce3259f67ac (video/fb/fbfill: Fix potential integer overflow)
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
It is minimal possibility that the values being used here will overflow.
So, change the code to use the safemath function grub_mul() to ensure
that doesn't happen.
Fixes: CID 73761
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The calculation of the unsigned 64-bit value is being generated by
multiplying 2, signed or unsigned, 32-bit integers which may overflow
before promotion to unsigned 64-bit. Fix all of them.
Fixes: CID 73703, CID 73767, CID 73833
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The multiplication of 2 unsigned 32-bit integers may overflow before
promotion to unsigned 64-bit. We should ensure that the multiplication
is done with overflow detection. Additionally, use grub_sub() for
subtraction.
Fixes: CID 73640, CID 73697, CID 73702, CID 73823
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>