From ab52630d0644e42a75eb88b78b9a9d7438a6fbeb Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 30 Sep 2019 18:45:43 +1000 Subject: [PATCH] Catch buffer overruns --- Tests/images/fli_overrun.bin | Bin 0 -> 188 bytes Tests/images/pcx_overrun.bin | Bin 0 -> 258 bytes Tests/images/sgi_overrun.bin | Bin 0 -> 4096 bytes Tests/test_image.py | 9 +++++++++ src/libImaging/FliDecode.c | 14 +++++++++++--- src/libImaging/PcxDecode.c | 5 +++++ src/libImaging/SgiRleDecode.c | 5 +++++ 7 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 Tests/images/fli_overrun.bin create mode 100644 Tests/images/pcx_overrun.bin create mode 100644 Tests/images/sgi_overrun.bin diff --git a/Tests/images/fli_overrun.bin b/Tests/images/fli_overrun.bin new file mode 100644 index 0000000000000000000000000000000000000000..e1e8c59017903bb6370a8a52962d3b2bb7957225 GIT binary patch literal 188 zcmd;cVqg$j&&bdKgd7aa3>plSfd&$__c<~!{QAfQ*Tu!mz`(-5$iTqFz#+rV&BV;0 fwCU{W)2x?8-GoJ)MMS-&rF|qM+!+M^vM~Sv@s|xH literal 0 HcmV?d00001 diff --git a/Tests/images/pcx_overrun.bin b/Tests/images/pcx_overrun.bin new file mode 100644 index 0000000000000000000000000000000000000000..ea46d2c1194b36495cce8448f35a3cd587da2ac8 GIT binary patch literal 258 zcmd;LWn^SzU}V_OIDtV+QHzm*f#E+00BPa?qX|M?1A+-*F}{Y1fXu}Te*8cEpa0GO vQ~wWsV0iQY;2#G2gFup>L^oJqH5(*&3?YN$hS&d(|3CPH@zDR*KmG#%!fPof literal 0 HcmV?d00001 diff --git a/Tests/images/sgi_overrun.bin b/Tests/images/sgi_overrun.bin new file mode 100644 index 0000000000000000000000000000000000000000..9a45d065ab81379400d0afbf16e97380d500f4bc GIT binary patch literal 4096 zcmeH{`*W1#7016z5|Zq`*L`<4`|fTw3AqV`BBJ625DFE20a37^2x`@oDuP0__6K{jovF6dnRc9NTicnoQ%k?!G|xZk?;T@o98qoYRp#NlGzzLwG3K;YNFgONWxDL3e3>exDT>K~C z(%XSy?*f;P0IoO=49@{0I)SS^VAO-a7kyyNPT)(7b@c&Yd<$^RKH%EHz?W%1X&7)_ z7chmfuje~AFy@W#1Jjy;=_`S+ehADQ1$>RZH!<$bvw_*ifNu-|<{SoY;d<*KU>@z~ zKLy;@0NnmKaAyWs*a6(l_=`3HOZoy!TY+z}H_IYm`R{>yX94$pA6UiQTaN&%Yk@US z0PXZ$OWSpS0oK!I!w-Os!+{5%1v(mm&7D9eXKM@d+gb@cvKiRM^LF-l2Yq%f1Rnns zc!IvWe-7*&4?KAe*gp<9a27bo^V4qthgkFBQ^2RT!oZ@zYJVS2E(@kBh%#17^5BXe*_qtC;umbaTk#PL0|&yu6-Vu zcnSHl-pPzTg|VhiB7gS!E9}d(9pwKRFylt@XMVFn@?S>&KLox$g#3>J-yB5#M}WC} zcOLt22TDNczp@^bA6Ng)4v4XnnV7-1-QN-#~_Iww(N# zZ$2RZU7UUPtA;V_E+hYwoPFll_&#TU8u`D+*&j*%tap$@{`9}FjQm;WP_7p*CI62( z`_svvzE@mC{%0PeUJRNaQ3t0&sbO2lm9cEea4({n6pp&iR|fhtamc~uV-JT zzQfs{O#a8ozLK*)kNnSZ_Bj``$mAx*n>~vB`R&XZME=bER^H8J|K{`E1^YSsMe=`? zv+t7sX3jp>#rKo{dElN_vIl2>5&3__*=LVeGIlF-iS}{!>D#uQ?D?&)TTcGJ;p|T( z|JOPDgUO$9HizWT_d5CB!)rPFHu>|so!`O^{~2@ipShX*xt_g^{6ArVtP`s#WQC|_ud~rf-}YZbdUEde=l9e7W62m`FK{14 z_p2xoMU9k=?)9Up{bI@rirz4>w2ykuiYYtk^pRzkFMYS-BE4!6SG}*e64{s>RG0RKy<(aknqKQIs~(Q9m835D2CxLJHti35v4bO zolUOVOJpaV-s#QXu+*wPnI0NjtiLLTeO{!h- zbg$UvY`zcqs4u#cz3EBs7}|@C;+q)%nTyWita(>#)u$esZ&AMs5v4bOot2wb>9v|Z z>8!nU#zuK6Kk?GNsW0j|E1qel_WOUp6`0DYda-wsbA)Om`n!o zpdxTGwrg97gk?Lv?>e^QCNl{qT|up%%GNa27c;Jvh{v5EF@<%JtLfq?3r-iL~qYi4BXjVauM4ms*a+u(o9>hV7KQWlpDU`xSm) z-%2GMJ)W>i?Jn2zlR-LRr7FE3l}ROik9T$u=Cau^m-GB=w&*!QK3DXeR3V#B_O+aN zMZ$KRGS^9#xf|%7vH~k<$0o)0V#}tL1IsKYnY0p>m2o>6sPJ~rOD4sM4H{HkJIO+LjIc$q@Amus$fDuTxT&4paQ{)N8j luvnKsAJerrcode = IMAGING_CODEC_OVERRUN; + return -1; + } + data = ptr + 6; switch (I16(ptr+4)) { case 4: case 11: /* FLI COLOR chunk */ @@ -198,7 +204,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt state->errcode = IMAGING_CODEC_UNKNOWN; return -1; } - ptr += I32(ptr); + advance = I32(ptr); + ptr += advance; + bytes -= advance; } return -1; /* end of frame */ diff --git a/src/libImaging/PcxDecode.c b/src/libImaging/PcxDecode.c index 4a5931bee73..67dcc1e0858 100644 --- a/src/libImaging/PcxDecode.c +++ b/src/libImaging/PcxDecode.c @@ -22,6 +22,11 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt UINT8 n; UINT8* ptr; + if (strcmp(im->mode, "1") == 0 && state->xsize > state->bytes * 8) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + ptr = buf; for (;;) { diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c index d8341f3e55f..8a81ba8e6c0 100644 --- a/src/libImaging/SgiRleDecode.c +++ b/src/libImaging/SgiRleDecode.c @@ -157,6 +157,11 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize]; c->rleoffset -= SGI_HEADER_SIZE; + if (c->rleoffset + c->rlelength > c->bufsize) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + /* row decompression */ if (c->bpc ==1) { if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands))