From d73ad9f5680b289ba9cadc2355b75a3cea05a38f Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Sat, 10 Aug 2024 00:15:36 +0800 Subject: [PATCH] erofs-utils: lib: fix heap-buffer-overflow on read Wrap up into kite_mf_hc3_skip() for now. Fixes: 861037f4fc15 ("erofs-utils: add a built-in DEFLATE compressor") Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20240809161536.3961647-1-hsiangkao@linux.alibaba.com --- lib/kite_deflate.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/kite_deflate.c b/lib/kite_deflate.c index e52e382..8581834 100644 --- a/lib/kite_deflate.c +++ b/lib/kite_deflate.c @@ -746,7 +746,7 @@ int kite_mf_getmatches_hc3(struct kite_matchfinder *mf, u16 depth, u16 bestlen) unsigned int v, hv, i, k, p, wsiz; if (mf->end - cur < bestlen + 1) - return 0; + return -1; v = get_unaligned((u16 *)cur); hv = v ^ crc_ccitt_table[cur[2]]; @@ -795,6 +795,14 @@ int kite_mf_getmatches_hc3(struct kite_matchfinder *mf, u16 depth, u16 bestlen) return k - 1; } +static void kite_mf_hc3_skip(struct kite_matchfinder *mf) +{ + if (kite_mf_getmatches_hc3(mf, 0, 2) >= 0) + return; + mf->offset++; + /* mf->cyclic_pos = (mf->cyclic_pos + 1) & (mf->wsiz - 1); */ +} + /* let's align with zlib */ static const struct kite_matchfinder_cfg { u16 good_length; /* reduce lazy search above this match length */ @@ -1057,7 +1065,7 @@ static bool kite_deflate_fast(struct kite_deflate *s) int matches = kite_mf_getmatches_hc3(mf, mf->depth, kMatchMinLen - 1); - if (matches) { + if (matches > 0) { unsigned int len = mf->matches[matches].len; unsigned int dist = mf->matches[matches].dist; @@ -1072,7 +1080,7 @@ static bool kite_deflate_fast(struct kite_deflate *s) s->pos_in += len; /* skip the rest bytes */ while (--len) - (void)kite_mf_getmatches_hc3(mf, 0, 0); + kite_mf_hc3_skip(mf); } else { nomatch: mf->matches[0].dist = s->in[s->pos_in]; @@ -1115,17 +1123,19 @@ static bool kite_deflate_slow(struct kite_deflate *s) if (len0 < mf->max_lazy) { matches = kite_mf_getmatches_hc3(mf, mf->depth >> (len0 >= mf->good_len), len0); - if (matches) { + if (matches > 0) { len = mf->matches[matches].len; if (len == kMatchMinLen && mf->matches[matches].dist > ZLIB_DISTANCE_TOO_FAR) { matches = 0; len = kMatchMinLen - 1; } + } else { + matches = 0; } } else { matches = 0; - (void)kite_mf_getmatches_hc3(mf, 0, 0); + kite_mf_hc3_skip(mf); } if (len < len0) { @@ -1136,7 +1146,7 @@ static bool kite_deflate_slow(struct kite_deflate *s) s->pos_in += --len0; /* skip the rest bytes */ while (--len0) - (void)kite_mf_getmatches_hc3(mf, 0, 0); + kite_mf_hc3_skip(mf); s->prev_valid = false; s->prev_longest = 0; } else { -- 2.34.1