In grub-core/video/readers/jpeg.c, the height and width of a JPEG image don't
have an upper limit for how big the JPEG image can be. In Coverity, this is
getting flagged as an untrusted loop bound. This issue can also seen in PNG and
TGA format images as well but Coverity isn't flagging it. To prevent this, the
constant IMAGE_HW_MAX_PX is being added to include/grub/bitmap.h, which has
a value of 16384, to act as an artificial limit and restrict the height and
width of images. This value was picked as it is double the current max
resolution size, which is 8K.
Fixes: CID 292450
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Certain 1 px wide images caused a wild pointer write in
grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
we have the following loop:
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
We did not check if vb * width >= hb * nc1.
On a 64-bit platform, if that turns out to be negative, it will underflow,
be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
we see data->bitmap_ptr jump, e.g.:
0x6180_0000_0480 to
0x6181_0000_0498
^
~--- carry has occurred and this pointer is now far away from
any object.
On a 32-bit platform, it will decrement the pointer, creating a pointer
that won't crash but will overwrite random data.
Catch the underflow and error out.
Fixes: CVE-2021-3697
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
An invalid file could contain multiple start of stream blocks, which
would cause us to reallocate and leak our bitmap. Refuse to handle
multiple start of streams.
Additionally, fix a grub_error() call formatting.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Fix a memory leak where an invalid file could cause us to reallocate
memory for a huffman table we had already allocated memory for.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Fuzzing revealed some inputs that were taking a long time, potentially
forever, because they did not bail quickly upon encountering an I/O error.
Try to catch I/O errors sooner and bail out.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
ASAN picked up two OOB global reads: we weren't checking if some code
values fit within the cplens or cpdext arrays. Check and throw an error
if not.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In fuzzing we observed crashes where a code would attempt to be inserted
into a huffman table before the start, leading to a set of heap OOB reads
and writes as table entries with negative indices were shifted around and
the new code written in.
Catch the case where we would underflow the array and bail.
Fixes: CVE-2021-3696
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
A 16-bit greyscale PNG without alpha is processed in the following loop:
for (i = 0; i < (data->image_width * data->image_height);
i++, d1 += 4, d2 += 2)
{
d1[R3] = d2[1];
d1[G3] = d2[1];
d1[B3] = d2[1];
}
The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
but there are only 3 bytes allocated for storage. This means that image
data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
out of every 4 following the end of the image.
This has existed since greyscale support was added in 2013 in commit
3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
and attempting to load it causes grub-emu to crash - I don't think this code
has ever worked.
Delete all PNG greyscale support.
Fixes: CVE-2021-3695
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This causes the bitmap to be leaked. Do not permit multiple image headers.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Fuzzing revealed some inputs that were taking a long time, potentially
forever, because they did not bail quickly upon encountering an I/O error.
Try to catch I/O errors sooner and bail out.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The value of next_marker is adjusted based on the word sized value
read from data->file.
The updated next_marker value should reference a location in the file
just beyond the huffman table, and as such should not have a value
larger than the size of the file.
Fixes: CID 73657
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When a start of stream marker is encountered, we call grub_jpeg_decode_sos()
which allocates space for a bitmap.
When a restart marker is encountered, we call grub_jpeg_decode_data() which
then fills in that bitmap.
If we get a restart marker before the start of stream marker, we will
attempt to write to a bitmap_ptr that hasn't been allocated. Catch this
and bail out. This fixes an attempt to write to NULL.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The key line is:
du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
jpeg_zigzag_order is grub_uint8_t[64].
I don't understand JPEG decoders quite well enough to explain what's
going on here. However, I observe sometimes pos=64, which leads to an
OOB read of the jpeg_zigzag_order global then an OOB write to du.
That leads to various unpleasant memory corruption conditions.
Catch where pos >= ARRAY_SIZE(jpeg_zigzag_order) and bail.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Our decoder only supports 2 quantization tables. If a file asks for
a quantization table with index > 1, reject it.
Similarly, our decoder only supports 4 Huffman tables. If a file asks
for a Huffman table with index > 3, reject it.
This fixes some out of bounds reads. It's not clear what degree of control
over subsequent execution could be gained by someone who can carefully
set up the contents of memory before loading an invalid JPEG file.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
While it may never happen, and potentially could be caught at the end of
the function, it is worth checking up front for a bad reference to the
next marker just in case of a maliciously crafted file being provided.
Fixes: CID 73694
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This attempts to fix the places where we do the following where
arithmetic_expr may include unvalidated data:
X = grub_malloc(arithmetic_expr);
It accomplishes this by doing the arithmetic ahead of time using grub_add(),
grub_sub(), grub_mul() and testing for overflow before proceeding.
Among other issues, this fixes:
- allocation of integer overflow in grub_video_bitmap_create()
reported by Chris Coulson,
- allocation of integer overflow in grub_png_decode_image_header()
reported by Chris Coulson,
- allocation of integer overflow in grub_squash_read_symlink()
reported by Chris Coulson,
- allocation of integer overflow in grub_ext2_read_symlink()
reported by Chris Coulson,
- allocation of integer overflow in read_section_as_string()
reported by Chris Coulson.
Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This modifies most of the places we do some form of:
X = malloc(Y * Z);
to use calloc(Y, Z) instead.
Among other issues, this fixes:
- allocation of integer overflow in grub_png_decode_image_header()
reported by Chris Coulson,
- allocation of integer overflow in luks_recover_key()
reported by Chris Coulson,
- allocation of integer overflow in grub_lvm_detect()
reported by Chris Coulson.
Fixes: CVE-2020-14308
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Let's provide file type info to the I/O layer. This way verifiers
framework and its users will be able to differentiate files and verify
only required ones.
This is preparatory patch.
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
In util/getroot and efidisk slightly modify exitsing comment to mostly
retain it but still make GCC7 compliant with respect to fall through
annotation.
In grub-core/lib/xzembed/xz_dec_lzma2.c it adds same comments as
upstream.
In grub-core/tests/setjmp_tets.c declare functions as "noreturn" to
suppress GCC7 warning.
In grub-core/gnulib/regexec.c use new __attribute__, because existing
annotation is not recognized by GCC7 parser (which requires that comment
immediately precedes case statement).
Otherwise add FALLTHROUGH comment.
Closes: 50598
* grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define.
(JPEG_MARKER_RST0): Likewise.
(JPEG_MARKER_RST1): Likewise.
(JPEG_MARKER_RST2): Likewise.
(JPEG_MARKER_RST3): Likewise.
(JPEG_MARKER_RST4): Likewise.
(JPEG_MARKER_RST5): Likewise.
(JPEG_MARKER_RST6): Likewise.
(JPEG_MARKER_RST7): Likewise.
(grub_jpeg_data): New fields dri, r1, bitmap_ptr.
(grub_jpeg_decode_dri): New function.
(grub_jpeg_decode_sos): Move image data related part into
grub_jpeg_decode_data function.
(grub_jpeg_decode_data): New function.
(grub_jpeg_reset): New function.
(grub_jpeg_decode_jpeg): Handle new markers.