1*4882a593SmuzhiyunFrom 78829f0c230680e386fff9f420bb1631bc20f761 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 3*4882a593SmuzhiyunDate: Thu, 9 Jul 2020 03:05:23 +0000 4*4882a593SmuzhiyunSubject: [PATCH] lzma: Make sure we don't dereference past array 5*4882a593SmuzhiyunMIME-Version: 1.0 6*4882a593SmuzhiyunContent-Type: text/plain; charset=UTF-8 7*4882a593SmuzhiyunContent-Transfer-Encoding: 8bit 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunThe two dimensional array p->posSlotEncoder[4][64] is being dereferenced 10*4882a593Smuzhiyunusing the GetLenToPosState() macro which checks if len is less than 5, 11*4882a593Smuzhiyunand if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294. 12*4882a593SmuzhiyunObviously we don't want to dereference that far out so we check if the 13*4882a593Smuzhiyunposition found is greater or equal kNumLenToPosStates (4) and bail out. 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunN.B.: Upstream LZMA 18.05 and later has this function completely rewritten 16*4882a593Smuzhiyunwithout any history. 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunFixes: CID 51526 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunSigned-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 21*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 22*4882a593SmuzhiyunSigned-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 23*4882a593Smuzhiyun--- 24*4882a593Smuzhiyun grub-core/lib/LzmaEnc.c | 10 ++++++++-- 25*4882a593Smuzhiyun 1 file changed, 8 insertions(+), 2 deletions(-) 26*4882a593Smuzhiyun 27*4882a593Smuzhiyundiff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c 28*4882a593Smuzhiyunindex f2ec04a8c..753e56a95 100644 29*4882a593Smuzhiyun--- a/grub-core/lib/LzmaEnc.c 30*4882a593Smuzhiyun+++ b/grub-core/lib/LzmaEnc.c 31*4882a593Smuzhiyun@@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize 32*4882a593Smuzhiyun } 33*4882a593Smuzhiyun else 34*4882a593Smuzhiyun { 35*4882a593Smuzhiyun- UInt32 posSlot; 36*4882a593Smuzhiyun+ UInt32 posSlot, lenToPosState; 37*4882a593Smuzhiyun RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); 38*4882a593Smuzhiyun p->state = kMatchNextStates[p->state]; 39*4882a593Smuzhiyun LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 40*4882a593Smuzhiyun pos -= LZMA_NUM_REPS; 41*4882a593Smuzhiyun GetPosSlot(pos, posSlot); 42*4882a593Smuzhiyun- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); 43*4882a593Smuzhiyun+ lenToPosState = GetLenToPosState(len); 44*4882a593Smuzhiyun+ if (lenToPosState >= kNumLenToPosStates) 45*4882a593Smuzhiyun+ { 46*4882a593Smuzhiyun+ p->result = SZ_ERROR_DATA; 47*4882a593Smuzhiyun+ return CheckErrors(p); 48*4882a593Smuzhiyun+ } 49*4882a593Smuzhiyun+ RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot); 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun if (posSlot >= kStartPosModelIndex) 52*4882a593Smuzhiyun { 53*4882a593Smuzhiyun-- 54*4882a593Smuzhiyun2.26.2 55*4882a593Smuzhiyun 56