- Avoid reading overly long compressed data;

 - Increase temporary buffer to keep inflight compressed data to 128k.

Cc: Chengyu Zhu <[email protected]>
Signed-off-by: Gao Xiang <[email protected]>
---
 lib/gzran.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/lib/gzran.c b/lib/gzran.c
index 1136d04..0238d19 100644
--- a/lib/gzran.c
+++ b/lib/gzran.c
@@ -222,15 +222,24 @@ static ssize_t erofs_gzran_ios_vfpread(struct erofs_vfile 
*vf, void *buf, size_t
        struct erofs_gzran_iostream *ios =
                (struct erofs_gzran_iostream *)vf->payload;
        struct erofs_gzran_cutpoint *cp = ios->cp;
-       u8 src[1 << 14], discard[EROFS_GZRAN_WINSIZE];
-       unsigned int bits;
+       u8 src[131072], discard[EROFS_GZRAN_WINSIZE];
+       union {
+               unsigned int bits, i;
+       } u;
        bool skip = true;
-       u64 inpos;
+       u64 inpos, remin;
        z_stream strm;
        int ret;
 
-       while (cp < ios->cp + ios->entries - 1 && cp[1].outpos <= offset)
+       if (offset == ~0ULL) {
+               DBG_BUGON(1);
+               return -EIO;
+       }
+
+       while (cp[1].outpos <= offset)
                ++cp;
+       for (u.i = 1; cp[u.i].outpos < offset + len; ++u.i);
+       remin = (cp[u.i].in_bitpos >> 3) + !!(cp[u.i].in_bitpos & 7);
 
        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
@@ -241,20 +250,21 @@ static ssize_t erofs_gzran_ios_vfpread(struct erofs_vfile 
*vf, void *buf, size_t
        if (ret != Z_OK)
                return -EFAULT;
 
-       bits = cp->in_bitpos & 7;
-       inpos = (cp->in_bitpos >> 3) - (bits ? 1 : 0);
-       ret = erofs_io_pread(ios->vin, src, sizeof(src), inpos);
+       u.bits = cp->in_bitpos & 7;
+       inpos = (cp->in_bitpos >> 3) - (u.bits ? 1 : 0);
+       remin -= inpos;
+       ret = erofs_io_pread(ios->vin, src, min(remin, sizeof(src)), inpos);
        if (ret < 0)
                return ret;
-
-       if (bits) {
-               inflatePrime(&strm, bits, src[0] >> (8 - bits));
+       if (u.bits) {
+               inflatePrime(&strm, u.bits, src[0] >> (8 - u.bits));
                strm.next_in = src + 1;
                strm.avail_in = ret - 1;
        } else {
                strm.next_in = src;
                strm.avail_in = ret;
        }
+       remin -= ret;
        inpos += ret;
        (void)inflateSetDictionary(&strm, cp->window, sizeof(cp->window));
 
@@ -278,13 +288,15 @@ static ssize_t erofs_gzran_ios_vfpread(struct erofs_vfile 
*vf, void *buf, size_t
                /* uncompress until avail_out filled, or end of stream */
                do {
                        if (!strm.avail_in) {
-                               ret = erofs_io_pread(ios->vin, src, sizeof(src),
+                               ret = erofs_io_pread(ios->vin, src,
+                                                    min(remin, sizeof(src)),
                                                     inpos);
                                if (ret < 0)
                                        return ret;
                                if (!ret)
                                        return -EIO;
                                inpos += ret;
+                               remin -= ret;
                                strm.avail_in = ret;
                                strm.next_in = src;
                        }
@@ -343,7 +355,7 @@ struct erofs_vfile *erofs_gzran_zinfo_open(struct 
erofs_vfile *vin,
                goto err_ios;
        }
 
-       ios->cp = malloc(sizeof(*ios->cp) * ios->entries);
+       ios->cp = malloc(sizeof(*ios->cp) * (ios->entries + 1));
        if (!ios->cp) {
                ret = -ENOMEM;
                goto err_ios;
@@ -364,6 +376,8 @@ struct erofs_vfile *erofs_gzran_zinfo_open(struct 
erofs_vfile *vin,
                ios->cp[i].outpos = le64_to_cpu(c->out);
                memcpy(ios->cp[i].window, c->window, sizeof(c->window));
        }
+       ios->cp[i].in_bitpos = -1;
+       ios->cp[i].outpos = ~0ULL;
        ios->vin = vin;
        vf->ops = &erofs_gzran_ios_vfops;
        return vf;
-- 
2.43.5


Reply via email to