wok-next rev 17990
qemu: apply cloop.u (again)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Apr 23 15:15:23 2015 +0200 (2015-04-23) |
parents | 9c8ef3fd3dcf |
children | 70c7a787c969 |
files | qemu/stuff/cloop.u |
line diff
1.1 --- a/qemu/stuff/cloop.u Thu Apr 23 13:30:18 2015 +0200 1.2 +++ b/qemu/stuff/cloop.u Thu Apr 23 15:15:23 2015 +0200 1.3 @@ -117,7 +117,7 @@ 1.4 } 1.5 1.6 static int cloop_open(BlockDriverState *bs, QDict *options, int flags, 1.7 -@@ -91,79 +169,104 @@ 1.8 +@@ -91,79 +169,97 @@ 1.9 MAX_BLOCK_SIZE / (1024 * 1024)); 1.10 return -EINVAL; 1.11 } 1.12 @@ -128,26 +128,14 @@ 1.13 } 1.14 s->n_blocks = be32_to_cpu(s->n_blocks); 1.15 1.16 -+ /* initialize zlib engine */ 1.17 -+ max_compressed_block_size = s->block_size + s->block_size/1000 + 12 + 4; 1.18 -+ s->compressed_block = g_malloc(max_compressed_block_size + 1); 1.19 -+ s->uncompressed_block = g_malloc(s->block_size); 1.20 -+ 1.21 -+ if (inflateInit(&s->zstream) != Z_OK) { 1.22 -+ ret = -EINVAL; 1.23 -+ goto fail; 1.24 -+ } 1.25 -+ 1.26 - /* read offsets */ 1.27 +- /* read offsets */ 1.28 - if (s->n_blocks > (UINT32_MAX - 1) / sizeof(uint64_t)) { 1.29 -+ if (s->n_blocks > (UINT32_MAX - 1) / sizeof(block_info)) { 1.30 - /* Prevent integer overflow */ 1.31 - error_setg(errp, "n_blocks %u must be %zu or less", 1.32 - s->n_blocks, 1.33 +- /* Prevent integer overflow */ 1.34 +- error_setg(errp, "n_blocks %u must be %zu or less", 1.35 +- s->n_blocks, 1.36 - (UINT32_MAX - 1) / sizeof(uint64_t)); 1.37 -+ (UINT32_MAX - 1) / sizeof(block_info)); 1.38 - return -EINVAL; 1.39 - } 1.40 +- return -EINVAL; 1.41 +- } 1.42 - offsets_size = (s->n_blocks + 1) * sizeof(uint64_t); 1.43 - if (offsets_size > 512 * 1024 * 1024) { 1.44 - /* Prevent ridiculous offsets_size which causes memory allocation to 1.45 @@ -159,27 +147,40 @@ 1.46 - return -EINVAL; 1.47 - } 1.48 - s->offsets = g_malloc(offsets_size); 1.49 ++ /* initialize zlib engine */ 1.50 ++ max_compressed_block_size = s->block_size + s->block_size/1000 + 12 + 4; 1.51 ++ s->compressed_block = g_malloc(max_compressed_block_size + 1); 1.52 ++ s->uncompressed_block = g_malloc(s->block_size); 1.53 + 1.54 +- ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size); 1.55 +- if (ret < 0) { 1.56 ++ if (inflateInit(&s->zstream) != Z_OK) { 1.57 ++ ret = -EINVAL; 1.58 + goto fail; 1.59 + } 1.60 + 1.61 +- for (i = 0; i < s->n_blocks + 1; i++) { 1.62 +- uint64_t size; 1.63 ++ /* read offsets */ 1.64 + if (s->n_blocks + 1 == 0) { 1.65 + cloop_tail tail; 1.66 + int64_t end = bdrv_getlength(bs->file); 1.67 + void *p; 1.68 + uint32_t toclen, len; 1.69 1.70 -- ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size); 1.71 -- if (ret < 0) { 1.72 -- goto fail; 1.73 -- } 1.74 -- 1.75 -- for (i = 0; i < s->n_blocks + 1; i++) { 1.76 -- uint64_t size; 1.77 +- s->offsets[i] = be64_to_cpu(s->offsets[i]); 1.78 +- if (i == 0) { 1.79 +- continue; 1.80 + ret = bdrv_pread(bs->file, end - sizeof(tail), &tail, sizeof(tail)); 1.81 + if (ret < 0) { 1.82 + goto fail; 1.83 -+ } 1.84 + } 1.85 1.86 -- s->offsets[i] = be64_to_cpu(s->offsets[i]); 1.87 -- if (i == 0) { 1.88 -- continue; 1.89 +- if (s->offsets[i] < s->offsets[i - 1]) { 1.90 +- error_setg(errp, "offsets not monotonically increasing at " 1.91 +- "index %u, image file is corrupt", i); 1.92 +- ret = -EINVAL; 1.93 +- goto fail; 1.94 + s->n_blocks = be32_to_cpu(tail.num_blocks); 1.95 + offsets_size = s->n_blocks * sizeof(block_info); 1.96 + if (offsets_size > 512 * 1024 * 1024) { 1.97 @@ -194,12 +195,18 @@ 1.98 + len = be32_to_cpu(tail.table_size); 1.99 + toclen = (be32_to_cpu(tail.index_size) & 255) * s->n_blocks; 1.100 1.101 -- if (s->offsets[i] < s->offsets[i - 1]) { 1.102 -- error_setg(errp, "offsets not monotonically increasing at " 1.103 -- "index %u, image file is corrupt", i); 1.104 +- size = s->offsets[i] - s->offsets[i - 1]; 1.105 + s->offsets = g_malloc(offsets_size); 1.106 + p = g_malloc(len); 1.107 -+ 1.108 + 1.109 +- /* Compressed blocks should be smaller than the uncompressed block size 1.110 +- * but maybe compression performed poorly so the compressed block is 1.111 +- * actually bigger. Clamp down on unrealistic values to prevent 1.112 +- * ridiculous s->compressed_block allocation. 1.113 +- */ 1.114 +- if (size > 2 * MAX_BLOCK_SIZE) { 1.115 +- error_setg(errp, "invalid compressed block size at index %u, " 1.116 +- "image file is corrupt", i); 1.117 + ret = bdrv_pread(bs->file, end - sizeof(tail) - len, p, len); 1.118 + if (ret < 0) { 1.119 + goto fail; 1.120 @@ -214,23 +221,15 @@ 1.121 goto fail; 1.122 } 1.123 - 1.124 -- size = s->offsets[i] - s->offsets[i - 1]; 1.125 -- 1.126 -- /* Compressed blocks should be smaller than the uncompressed block size 1.127 -- * but maybe compression performed poorly so the compressed block is 1.128 -- * actually bigger. Clamp down on unrealistic values to prevent 1.129 -- * ridiculous s->compressed_block allocation. 1.130 -- */ 1.131 -- if (size > 2 * MAX_BLOCK_SIZE) { 1.132 -- error_setg(errp, "invalid compressed block size at index %u, " 1.133 -- "image file is corrupt", i); 1.134 +- if (size > max_compressed_block_size) { 1.135 +- max_compressed_block_size = size; 1.136 + ret = inflate(&s->zstream, Z_FINISH); 1.137 + if (ret != Z_STREAM_END || s->zstream.total_out != toclen) { 1.138 - ret = -EINVAL; 1.139 - goto fail; 1.140 ++ ret = -EINVAL; 1.141 ++ goto fail; 1.142 } 1.143 + g_free(p); 1.144 -+ } 1.145 + } 1.146 + else { 1.147 + offsets_size = s->n_blocks * sizeof(block_info); 1.148 + if (offsets_size > 512 * 1024 * 1024) { 1.149 @@ -244,18 +243,15 @@ 1.150 + } 1.151 + s->offsets = g_malloc(offsets_size); 1.152 1.153 -- if (size > max_compressed_block_size) { 1.154 -- max_compressed_block_size = size; 1.155 -+ ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size); 1.156 -+ if (ret < 0) { 1.157 -+ goto fail; 1.158 - } 1.159 - } 1.160 -- 1.161 - /* initialize zlib engine */ 1.162 - s->compressed_block = g_malloc(max_compressed_block_size + 1); 1.163 - s->uncompressed_block = g_malloc(s->block_size); 1.164 - if (inflateInit(&s->zstream) != Z_OK) { 1.165 ++ ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size); 1.166 ++ if (ret < 0) { 1.167 ++ goto fail; 1.168 ++ } 1.169 ++ } 1.170 + ret = build_index(s->offsets, s->n_blocks); 1.171 + if (ret) { 1.172 + error_setg(errp, "invalid compressed block size at index %u, " 1.173 @@ -267,7 +263,7 @@ 1.174 s->current_block = s->n_blocks; 1.175 1.176 s->sectors_per_block = s->block_size/512; 1.177 -@@ -184,10 +287,10 @@ 1.178 +@@ -184,10 +280,10 @@ 1.179 1.180 if (s->current_block != block_num) { 1.181 int ret;