~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to block/cloop.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-25 22:31:43 UTC
  • mfrom: (1.8.5)
  • Revision ID: package-import@ubuntu.com-20140225223143-odhqxfc60wxrjl15
Tags: 2.0.0~rc1+dfsg-0ubuntu1
* Merge 2.0.0-rc1
* debian/rules: consolidate ppc filter entries.
* Move qemu-system-arch64 into qemu-system-arm
* debian/patches/define-trusty-machine-type.patch: define a trusty machine
  type, currently the same as pc-i440fx-2.0, to put is in a better position
  to enable live migrations from trusty onward.  (LP: #1294823)
* debian/control: build-dep on libfdt >= 1.4.0  (LP: #1295072)
* Merge latest upstream git to commit dc9528f
* Debian/rules:
  - remove -enable-uname-release=2.6.32
  - don't make the aarch64 target Ubuntu-specific.
* Remove patches which are now upstream:
  - fix-smb-security-share.patch
  - slirp-smb-redirect-port-445-too.patch 
  - linux-user-Implement-sendmmsg-syscall.patch (better version is upstream)
  - signal-added-a-wrapper-for-sigprocmask-function.patch
  - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
  - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch
  - ubuntu/ppc-force-cpu-threads-count-to-be-power-of-2.patch
* add link for /usr/share/qemu/bios-256k.bin
* Remove all linaro patches.
* Remove all arm64/ patches.  Many but not all are upstream.
* Remove CVE-2013-4377.patch which is upstream.
* debian/control-in: don't make qemu-system-aarch64 ubuntu-specific

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "qemu/module.h"
27
27
#include <zlib.h>
28
28
 
 
29
/* Maximum compressed block size */
 
30
#define MAX_BLOCK_SIZE (64 * 1024 * 1024)
 
31
 
29
32
typedef struct BDRVCloopState {
30
33
    CoMutex lock;
31
34
    uint32_t block_size;
68
71
        return ret;
69
72
    }
70
73
    s->block_size = be32_to_cpu(s->block_size);
 
74
    if (s->block_size % 512) {
 
75
        error_setg(errp, "block_size %u must be a multiple of 512",
 
76
                   s->block_size);
 
77
        return -EINVAL;
 
78
    }
 
79
    if (s->block_size == 0) {
 
80
        error_setg(errp, "block_size cannot be zero");
 
81
        return -EINVAL;
 
82
    }
 
83
 
 
84
    /* cloop's create_compressed_fs.c warns about block sizes beyond 256 KB but
 
85
     * we can accept more.  Prevent ridiculous values like 4 GB - 1 since we
 
86
     * need a buffer this big.
 
87
     */
 
88
    if (s->block_size > MAX_BLOCK_SIZE) {
 
89
        error_setg(errp, "block_size %u must be %u MB or less",
 
90
                   s->block_size,
 
91
                   MAX_BLOCK_SIZE / (1024 * 1024));
 
92
        return -EINVAL;
 
93
    }
71
94
 
72
95
    ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
73
96
    if (ret < 0) {
76
99
    s->n_blocks = be32_to_cpu(s->n_blocks);
77
100
 
78
101
    /* read offsets */
79
 
    offsets_size = s->n_blocks * sizeof(uint64_t);
 
102
    if (s->n_blocks > (UINT32_MAX - 1) / sizeof(uint64_t)) {
 
103
        /* Prevent integer overflow */
 
104
        error_setg(errp, "n_blocks %u must be %zu or less",
 
105
                   s->n_blocks,
 
106
                   (UINT32_MAX - 1) / sizeof(uint64_t));
 
107
        return -EINVAL;
 
108
    }
 
109
    offsets_size = (s->n_blocks + 1) * sizeof(uint64_t);
 
110
    if (offsets_size > 512 * 1024 * 1024) {
 
111
        /* Prevent ridiculous offsets_size which causes memory allocation to
 
112
         * fail or overflows bdrv_pread() size.  In practice the 512 MB
 
113
         * offsets[] limit supports 16 TB images at 256 KB block size.
 
114
         */
 
115
        error_setg(errp, "image requires too many offsets, "
 
116
                   "try increasing block size");
 
117
        return -EINVAL;
 
118
    }
80
119
    s->offsets = g_malloc(offsets_size);
81
120
 
82
121
    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
84
123
        goto fail;
85
124
    }
86
125
 
87
 
    for(i=0;i<s->n_blocks;i++) {
 
126
    for (i = 0; i < s->n_blocks + 1; i++) {
 
127
        uint64_t size;
 
128
 
88
129
        s->offsets[i] = be64_to_cpu(s->offsets[i]);
89
 
        if (i > 0) {
90
 
            uint32_t size = s->offsets[i] - s->offsets[i - 1];
91
 
            if (size > max_compressed_block_size) {
92
 
                max_compressed_block_size = size;
93
 
            }
 
130
        if (i == 0) {
 
131
            continue;
 
132
        }
 
133
 
 
134
        if (s->offsets[i] < s->offsets[i - 1]) {
 
135
            error_setg(errp, "offsets not monotonically increasing at "
 
136
                       "index %u, image file is corrupt", i);
 
137
            ret = -EINVAL;
 
138
            goto fail;
 
139
        }
 
140
 
 
141
        size = s->offsets[i] - s->offsets[i - 1];
 
142
 
 
143
        /* Compressed blocks should be smaller than the uncompressed block size
 
144
         * but maybe compression performed poorly so the compressed block is
 
145
         * actually bigger.  Clamp down on unrealistic values to prevent
 
146
         * ridiculous s->compressed_block allocation.
 
147
         */
 
148
        if (size > 2 * MAX_BLOCK_SIZE) {
 
149
            error_setg(errp, "invalid compressed block size at index %u, "
 
150
                       "image file is corrupt", i);
 
151
            ret = -EINVAL;
 
152
            goto fail;
 
153
        }
 
154
 
 
155
        if (size > max_compressed_block_size) {
 
156
            max_compressed_block_size = size;
94
157
        }
95
158
    }
96
159
 
180
243
static void cloop_close(BlockDriverState *bs)
181
244
{
182
245
    BDRVCloopState *s = bs->opaque;
183
 
    if (s->n_blocks > 0) {
184
 
        g_free(s->offsets);
185
 
    }
 
246
    g_free(s->offsets);
186
247
    g_free(s->compressed_block);
187
248
    g_free(s->uncompressed_block);
188
249
    inflateEnd(&s->zstream);