From: Daniel Axtens <d...@axtens.net> In huft_build(), "v" is a table of values in order of bit length. The code later (when setting up table entries in "r") assumes that all elements of this array corresponding to a code are initialized and less than N_MAX. However, it doesn't enforce this.
With sufficiently manipulated inputs (e.g. from fuzzing), there can be elements of "v" that are not filled. Therefore a lookup into "e" or "d" will use an uninitialized value. This can lead to an invalid/OOB read on those values, often leading to a crash. Signed-off-by: Daniel Axtens <d...@axtens.net> Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> --- grub-core/io/gzio.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 4236f0fd4..19adebeed 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -507,6 +507,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ } /* Make a table of values in order of bit lengths */ + grub_memset (v, N_MAX, ARRAY_SIZE (v)); p = b; i = 0; do @@ -588,11 +589,18 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ r.v.n = (ush) (*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } - else + else if (*p < N_MAX) { r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } + else + { + /* Detected an uninitialised value, abort. */ + if (h) + huft_free (u[0]); + return 2; + } /* fill code-like entries with r */ f = 1 << (k - w); -- 2.11.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel