wok rev 17989

qemu: apply cloop.u
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Apr 23 13:30:18 2015 +0200 (2015-04-23)
parents c73f683146cf
children 9375c1de578d
files qemu/receipt qemu/stuff/cloop.u
line diff
     1.1 --- a/qemu/receipt	Thu Apr 23 01:34:37 2015 +0300
     1.2 +++ b/qemu/receipt	Thu Apr 23 13:30:18 2015 +0200
     1.3 @@ -20,7 +20,7 @@
     1.4  # Rules to configure and make the package.
     1.5  compile_rules()
     1.6  {
     1.7 -#	patch -p0 < $stuff/cloop.u
     1.8 +	patch -p0 < $stuff/cloop.u
     1.9  
    1.10  	TARGET="i386-softmmu, x86_64-softmmu, \
    1.11  	arm-softmmu, ppc-softmmu, mips-softmmu"
     2.1 --- a/qemu/stuff/cloop.u	Thu Apr 23 01:34:37 2015 +0300
     2.2 +++ b/qemu/stuff/cloop.u	Thu Apr 23 13:30:18 2015 +0200
     2.3 @@ -1,8 +1,8 @@
     2.4  --- block/cloop.c
     2.5  +++ block/cloop.c
     2.6 -@@ -26,11 +26,78 @@
     2.7 - #include "qemu/module.h"
     2.8 - #include <zlib.h>
     2.9 +@@ -29,11 +29,85 @@
    2.10 + /* Maximum compressed block size */
    2.11 + #define MAX_BLOCK_SIZE (64 * 1024 * 1024)
    2.12   
    2.13  +typedef struct cloop_tail {
    2.14  +	uint32_t table_size;
    2.15 @@ -16,7 +16,7 @@
    2.16  +	uint32_t optidx;	/* 32-bit index number */
    2.17  +} block_info;
    2.18  +
    2.19 -+static inline void build_index(block_info *offsets, unsigned long n)
    2.20 ++static inline int build_index(block_info *offsets, unsigned long n)
    2.21  +{
    2.22  +	uint32_t *ofs32 = (uint32_t *) offsets;
    2.23  +	uint64_t *ofs64 = (uint64_t *) offsets;
    2.24 @@ -26,17 +26,19 @@
    2.25  +			while (n--) {
    2.26  +				offsets[n].offset = be64_to_cpu(offsets[n].offset);
    2.27  +				offsets[n].size = ntohl(offsets[n].size);
    2.28 ++        			if (offsets[n].size > 2 * MAX_BLOCK_SIZE)
    2.29 ++        				return n+1;
    2.30  +			}
    2.31 -+			// return (char *) "128BE accelerated knoppix 1.0";
    2.32  +		}
    2.33  +		else { /* V2.0 */
    2.34  +			uint64_t last = be64_to_cpu(ofs64[n - 1]);
    2.35  +			while (n--) {
    2.36  +				offsets[n].size = last - 
    2.37  +					(offsets[n].offset = be64_to_cpu(ofs64[n])); 
    2.38 ++        			if (offsets[n].size > 2 * MAX_BLOCK_SIZE)
    2.39 ++        				return n+1;
    2.40  +				last = offsets[n].offset;
    2.41  +			}
    2.42 -+			// return (char *) "64BE v2.0";
    2.43  +		}
    2.44  +	}
    2.45  +	else if (ofs32[1] == 0) { /* V1.0 */
    2.46 @@ -44,31 +46,36 @@
    2.47  +		while (n--) {
    2.48  +			offsets[n].size = last - 
    2.49  +				(offsets[n].offset = le64_to_cpu(ofs64[n])); 
    2.50 ++        		if (offsets[n].size > 2 * MAX_BLOCK_SIZE)
    2.51 ++        			return n+1;
    2.52  +			last = offsets[n].offset;
    2.53  +		}
    2.54 -+		// return (char *) "64LE v1.0";
    2.55  +	}
    2.56  +	else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
    2.57  +		uint64_t last = ntohl(ofs32[n - 1]);
    2.58  +		while (n--) {
    2.59  +			offsets[n].size = last - 
    2.60  +				(offsets[n].offset = ntohl(ofs32[n])); 
    2.61 ++        		if (offsets[n].size > 2 * MAX_BLOCK_SIZE)
    2.62 ++        			return n+1;
    2.63  +			last = offsets[n].offset;
    2.64  +		}
    2.65 -+		// return (char *) "32BE v0.68";
    2.66  +	}
    2.67  +	else { /* V3.0 */
    2.68  +		unsigned long i;
    2.69  +		uint64_t j;
    2.70  +		
    2.71 -+		for (i = n; i-- > 0; )
    2.72 ++		for (i = n; i-- > 0; ) {
    2.73  +			offsets[i].size = ntohl(ofs32[i]); 
    2.74 ++        		if (offsets[i].size > 2 * MAX_BLOCK_SIZE)
    2.75 ++        			return i+1;
    2.76 ++		}
    2.77  +		for (i = 0, j = 128 + 4 + 4; i < n; i++) {
    2.78  +			offsets[i].offset = j;
    2.79  +			j += offsets[i].size;
    2.80  +		}
    2.81 -+		// return (char *) "32BE v3.0";
    2.82  +	}
    2.83 ++	return 0;
    2.84  +}
    2.85  +
    2.86   typedef struct BDRVCloopState {
    2.87 @@ -80,7 +87,7 @@
    2.88       uint32_t sectors_per_block;
    2.89       uint32_t current_block;
    2.90       uint8_t *compressed_block;
    2.91 -@@ -40,17 +107,21 @@
    2.92 +@@ -43,17 +117,21 @@
    2.93   
    2.94   static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
    2.95   {
    2.96 @@ -109,50 +116,87 @@
    2.97  +    return ret;
    2.98   }
    2.99   
   2.100 - static int cloop_open(BlockDriverState *bs, QDict *options, int flags)
   2.101 -@@ -74,32 +145,67 @@
   2.102 + static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
   2.103 +@@ -91,79 +169,104 @@
   2.104 +                    MAX_BLOCK_SIZE / (1024 * 1024));
   2.105 +         return -EINVAL;
   2.106 +     }
   2.107 +-
   2.108 +     ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
   2.109 +     if (ret < 0) {
   2.110 +         return ret;
   2.111       }
   2.112       s->n_blocks = be32_to_cpu(s->n_blocks);
   2.113   
   2.114 --    /* read offsets */
   2.115 --    offsets_size = s->n_blocks * sizeof(uint64_t);
   2.116 --    s->offsets = g_malloc(offsets_size);
   2.117  +    /* initialize zlib engine */
   2.118  +    max_compressed_block_size =  s->block_size + s->block_size/1000 + 12 + 4;
   2.119  +    s->compressed_block = g_malloc(max_compressed_block_size + 1);
   2.120  +    s->uncompressed_block = g_malloc(s->block_size);
   2.121 - 
   2.122 --    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.123 --    if (ret < 0) {
   2.124 ++
   2.125  +    if (inflateInit(&s->zstream) != Z_OK) {
   2.126  +        ret = -EINVAL;
   2.127 -         goto fail;
   2.128 ++        goto fail;
   2.129 ++    }
   2.130 ++
   2.131 +     /* read offsets */
   2.132 +-    if (s->n_blocks > (UINT32_MAX - 1) / sizeof(uint64_t)) {
   2.133 ++    if (s->n_blocks > (UINT32_MAX - 1) / sizeof(block_info)) {
   2.134 +         /* Prevent integer overflow */
   2.135 +         error_setg(errp, "n_blocks %u must be %zu or less",
   2.136 +                    s->n_blocks,
   2.137 +-                   (UINT32_MAX - 1) / sizeof(uint64_t));
   2.138 ++                   (UINT32_MAX - 1) / sizeof(block_info));
   2.139 +         return -EINVAL;
   2.140       }
   2.141 - 
   2.142 --    for(i=0;i<s->n_blocks;i++) {
   2.143 --        s->offsets[i] = be64_to_cpu(s->offsets[i]);
   2.144 --        if (i > 0) {
   2.145 --            uint32_t size = s->offsets[i] - s->offsets[i - 1];
   2.146 --            if (size > max_compressed_block_size) {
   2.147 --                max_compressed_block_size = size;
   2.148 --            }
   2.149 -+    /* read offsets */
   2.150 +-    offsets_size = (s->n_blocks + 1) * sizeof(uint64_t);
   2.151 +-    if (offsets_size > 512 * 1024 * 1024) {
   2.152 +-        /* Prevent ridiculous offsets_size which causes memory allocation to
   2.153 +-         * fail or overflows bdrv_pread() size.  In practice the 512 MB
   2.154 +-         * offsets[] limit supports 16 TB images at 256 KB block size.
   2.155 +-         */
   2.156 +-        error_setg(errp, "image requires too many offsets, "
   2.157 +-                   "try increasing block size");
   2.158 +-        return -EINVAL;
   2.159 +-    }
   2.160 +-    s->offsets = g_malloc(offsets_size);
   2.161  +    if (s->n_blocks + 1 == 0) {
   2.162  +        cloop_tail tail;
   2.163  +        int64_t end = bdrv_getlength(bs->file);
   2.164  +	void *p;
   2.165  +	uint32_t toclen, len; 
   2.166 -+
   2.167 + 
   2.168 +-    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.169 +-    if (ret < 0) {
   2.170 +-        goto fail;
   2.171 +-    }
   2.172 +-
   2.173 +-    for (i = 0; i < s->n_blocks + 1; i++) {
   2.174 +-        uint64_t size;
   2.175  +        ret = bdrv_pread(bs->file, end - sizeof(tail), &tail, sizeof(tail));
   2.176  +        if (ret < 0) {
   2.177  +            goto fail;
   2.178 -         }
   2.179 -+
   2.180 ++        }
   2.181 + 
   2.182 +-        s->offsets[i] = be64_to_cpu(s->offsets[i]);
   2.183 +-        if (i == 0) {
   2.184 +-            continue;
   2.185  +        s->n_blocks = be32_to_cpu(tail.num_blocks);
   2.186  +        offsets_size = s->n_blocks * sizeof(block_info);
   2.187 ++        if (offsets_size > 512 * 1024 * 1024) {
   2.188 ++            /* Prevent ridiculous offsets_size which causes memory allocation to
   2.189 ++             * fail or overflows bdrv_pread() size.  In practice the 512 MB
   2.190 ++             * offsets[] limit supports 16 TB images at 256 KB block size.
   2.191 ++             */
   2.192 ++            error_setg(errp, "image requires too many offsets, "
   2.193 ++                       "try increasing block size");
   2.194 ++            return -EINVAL;
   2.195 +         }
   2.196  +	len = be32_to_cpu(tail.table_size);
   2.197  +	toclen = (be32_to_cpu(tail.index_size) & 255) * s->n_blocks;
   2.198 -+
   2.199 + 
   2.200 +-        if (s->offsets[i] < s->offsets[i - 1]) {
   2.201 +-            error_setg(errp, "offsets not monotonically increasing at "
   2.202 +-                       "index %u, image file is corrupt", i);
   2.203  +        s->offsets = g_malloc(offsets_size);
   2.204  +	p = g_malloc(len);
   2.205  +
   2.206 @@ -166,37 +210,64 @@
   2.207  +        s->zstream.avail_out = toclen;
   2.208  +        ret = inflateReset(&s->zstream);
   2.209  +        if (ret != Z_OK) {
   2.210 -+            ret = -EINVAL;
   2.211 -+            goto fail;
   2.212 -+        }
   2.213 +             ret = -EINVAL;
   2.214 +             goto fail;
   2.215 +         }
   2.216 +-
   2.217 +-        size = s->offsets[i] - s->offsets[i - 1];
   2.218 +-
   2.219 +-        /* Compressed blocks should be smaller than the uncompressed block size
   2.220 +-         * but maybe compression performed poorly so the compressed block is
   2.221 +-         * actually bigger.  Clamp down on unrealistic values to prevent
   2.222 +-         * ridiculous s->compressed_block allocation.
   2.223 +-         */
   2.224 +-        if (size > 2 * MAX_BLOCK_SIZE) {
   2.225 +-            error_setg(errp, "invalid compressed block size at index %u, "
   2.226 +-                       "image file is corrupt", i);
   2.227  +        ret = inflate(&s->zstream, Z_FINISH);
   2.228  +        if (ret != Z_STREAM_END || s->zstream.total_out != toclen) {
   2.229 -+            ret = -EINVAL;
   2.230 -+            goto fail;
   2.231 -+        }
   2.232 +             ret = -EINVAL;
   2.233 +             goto fail;
   2.234 +         }
   2.235  +	g_free(p);
   2.236 -     }
   2.237 ++    }
   2.238  +    else {
   2.239  +        offsets_size = s->n_blocks * sizeof(block_info);
   2.240 ++        if (offsets_size > 512 * 1024 * 1024) {
   2.241 ++            /* Prevent ridiculous offsets_size which causes memory allocation to
   2.242 ++             * fail or overflows bdrv_pread() size.  In practice the 512 MB
   2.243 ++             * offsets[] limit supports 16 TB images at 256 KB block size.
   2.244 ++             */
   2.245 ++            error_setg(errp, "image requires too many offsets, "
   2.246 ++                       "try increasing block size");
   2.247 ++            return -EINVAL;
   2.248 ++        }
   2.249  +        s->offsets = g_malloc(offsets_size);
   2.250   
   2.251 +-        if (size > max_compressed_block_size) {
   2.252 +-            max_compressed_block_size = size;
   2.253 ++        ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.254 ++        if (ret < 0) {
   2.255 ++            goto fail;
   2.256 +         }
   2.257 +     }
   2.258 +-
   2.259  -    /* initialize zlib engine */
   2.260  -    s->compressed_block = g_malloc(max_compressed_block_size + 1);
   2.261  -    s->uncompressed_block = g_malloc(s->block_size);
   2.262  -    if (inflateInit(&s->zstream) != Z_OK) {
   2.263 --        ret = -EINVAL;
   2.264 --        goto fail;
   2.265 -+        ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.266 -+        if (ret < 0) {
   2.267 -+            goto fail;
   2.268 -+        }
   2.269 ++    ret = build_index(s->offsets, s->n_blocks);
   2.270 ++    if (ret) {
   2.271 ++        error_setg(errp, "invalid compressed block size at index %u, "
   2.272 ++                   "image file is corrupt", ret-1);
   2.273 +         ret = -EINVAL;
   2.274 +         goto fail;
   2.275       }
   2.276 -+    build_index(s->offsets, s->n_blocks);
   2.277  +
   2.278       s->current_block = s->n_blocks;
   2.279   
   2.280       s->sectors_per_block = s->block_size/512;
   2.281 -@@ -120,10 +226,10 @@
   2.282 +@@ -184,10 +287,10 @@
   2.283   
   2.284       if (s->current_block != block_num) {
   2.285           int ret;