diff mbox

[U-Boot] zlib: handle overflow while calculating available stream input size

Message ID 1318696372-13816-1-git-send-email-agust@denx.de
State Accepted
Commit 92faa8b109180fa28ec899479f676e62a3a391b7
Headers show

Commit Message

Anatolij Gustschin Oct. 15, 2011, 4:32 p.m. UTC
If compressed data is located in sectors at the end of the flash and
it's offset + input stream size > 0xFFFFFFFF, the uncompressing time
is very long, since processing of the stream is done bytewise (and
not blockwise) due to overflow in inflate_fast() while calculation
and checking for enough input available.

Check for this overflow condition and limit the available stream
input size to the actually max. possible input size. This fixes
the problem.

The issue is easily reproduceable by placing a gziped bitmap in flash,
e.g. at FFF80000, and running 'bmp' commands like 'bmp info FFF80000'
or 'bmp display FFF80000'. The uncompressing can take up to 3 sec.
whereas it should normaly take a fraction of a second. If the
'splashimage' environment variable points to this address, the
booting time also increases significantly.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Note:
  there are 6 errors and 4 warning reported by checkpatch.pl
  for this patch. I didn't fix them intentionally and used the
  coding style of the zlib code here. The code would look ugly
  otherwise.

 lib/zlib/inffast.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

Comments

Mike Frysinger Oct. 15, 2011, 5:10 p.m. UTC | #1
On Saturday 15 October 2011 12:32:52 Anatolij Gustschin wrote:
> If compressed data is located in sectors at the end of the flash and
> it's offset + input stream size > 0xFFFFFFFF, the uncompressing time
> is very long, since processing of the stream is done bytewise (and
> not blockwise) due to overflow in inflate_fast() while calculation
> and checking for enough input available.
> 
> Check for this overflow condition and limit the available stream
> input size to the actually max. possible input size. This fixes
> the problem.
> 
> The issue is easily reproduceable by placing a gziped bitmap in flash,
> e.g. at FFF80000, and running 'bmp' commands like 'bmp info FFF80000'
> or 'bmp display FFF80000'. The uncompressing can take up to 3 sec.
> whereas it should normaly take a fraction of a second. If the
> 'splashimage' environment variable points to this address, the
> booting time also increases significantly.

can we send this to the upstream zlib project if it isn't there already and 
get feedback from them ?
-mike
Wolfgang Denk Oct. 17, 2011, 7:46 p.m. UTC | #2
Dear Anatolij Gustschin,

In message <1318696372-13816-1-git-send-email-agust@denx.de> you wrote:
> If compressed data is located in sectors at the end of the flash and
> it's offset + input stream size > 0xFFFFFFFF, the uncompressing time
> is very long, since processing of the stream is done bytewise (and
> not blockwise) due to overflow in inflate_fast() while calculation
> and checking for enough input available.
> 
> Check for this overflow condition and limit the available stream
> input size to the actually max. possible input size. This fixes
> the problem.
> 
> The issue is easily reproduceable by placing a gziped bitmap in flash,
> e.g. at FFF80000, and running 'bmp' commands like 'bmp info FFF80000'
> or 'bmp display FFF80000'. The uncompressing can take up to 3 sec.
> whereas it should normaly take a fraction of a second. If the
> 'splashimage' environment variable points to this address, the
> booting time also increases significantly.
> 
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
> Note:
>   there are 6 errors and 4 warning reported by checkpatch.pl
>   for this patch. I didn't fix them intentionally and used the
>   coding style of the zlib code here. The code would look ugly
>   otherwise.
> 
>  lib/zlib/inffast.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
index 8e823df..4834b0c 100644
--- a/lib/zlib/inffast.c
+++ b/lib/zlib/inffast.c
@@ -100,6 +100,14 @@  unsigned start;         /* inflate()'s starting value for strm->avail_out */
     state = (struct inflate_state FAR *)strm->state;
     in = strm->next_in - OFF;
     last = in + (strm->avail_in - 5);
+    if (in > last && strm->avail_in > 5) {
+        /*
+         * overflow detected, limit strm->avail_in to the
+         * max. possible size and recalculate last
+         */
+        strm->avail_in = 0xffffffff - (unsigned int)in;
+        last = in + (strm->avail_in - 5);
+    }
     out = strm->next_out - OFF;
     beg = out - (start - strm->avail_out);
     end = out + (strm->avail_out - 257);