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;