summaryrefslogtreecommitdiff
path: root/block/dmg.c
AgeCommit message (Collapse)AuthorFilesLines
2014-12-27block/dmg: validate more offsets and lengthsblock-dmg-2.3Peter Wu1-0/+14
Patch "block/dmg: validate chunk size to avoid overflow" is not enough to catch boundary issues as "info_length" was unchecked. This patch ensures that the read boundaries are valid. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: improve zeroes handlingPeter Wu1-5/+13
Disk images may contain large all-zeroes gaps (1.66k sectors or 812 MiB is seen in the real world). These blocks (type 2) do not need to be extracted into a temporary buffer, there is no need to allocate memory for these blocks nor to check its length. (For the test image, the maximum uncompressed size is 1054371 bytes, probably for a bzip2-compressed block.) Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: support bzip2 block entry typesPeter Wu1-3/+53
This patch adds support for bzip2-compressed block entries as introduced with OS X 10.4 (source: https://en.wikipedia.org/wiki/Apple_Disk_Image). It was tested against a 5.2G "OS X Yosemite" installation image which stores the BLXX block in the XML property list (instead of resource forks) and has over 5k chunks. New configure entries are added (--enable-bzip2 / --disable-bzip2) to control inclusion of bzip2 functionality (which requires linking against libbz2). The help message suggests that this option is needed for DMG files, but the tests are generic enough that other parts of QEMU can use bzip2 if needed. The identifiers are based on http://newosxbook.com/DMG.html. The decompression routines are based on the zlib case, but as there is no way to reset the decompression state (unlike zlib), memory is allocated and deallocated for every decompression. This should not be problematic as the decompression takes most of the time and as blocks are typically about/over 1 MiB in size, only one allocation is done every 2000 sectors. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: fix sector data offset calculationPeter Wu1-1/+15
This patch addresses two issues: - The data fork offset was not taken into account, resulting in failure to read an InstallESD.dmg file (5164763151 bytes) which had a non-zero DataForkOffset field. - The offset of the previous block ("partition") was unconditionally added to the current block because older files would start the input offset of a new block at zero. Newer files (including vlc-2.1.5.dmg, tuxpaint-0.9.15-macosx.dmg and OS X Yosemite [MAS].dmg) failed in reads because these files have a continuous input offset. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: set virtual size to a non-zero valuePeter Wu1-0/+8
Right now the virtual size is always reported as zero which makes it impossible to convert between formats. After this patch, the number of sectors will be read from the BLXX ("mish") header. To verify the behavior, the output of `dmg2img foo.dmg foo.img` was compared against `qemu-img convert -f dmg -O raw foo.dmg foo.raw`. The tests showed that the file contents are exactly the same, except that QEMU creates a slightly larger file (it matches the total sectors count). Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: process XML plistsPeter Wu1-0/+69
The format is simple enough to avoid using a full-blown XML parser. The offsets are based on the description at http://newosxbook.com/DMG.html Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: validate chunk size to avoid overflowPeter Wu1-1/+1
Previously the chunk size was not checked, allowing for a large memory allocation. This patch checks whether the chunks size is within the resource fork length. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: process a buffer instead of reading intsPeter Wu1-30/+30
As the decoded plist XML is not a pointer in the file, dmg_read_mish_block must be able to process a buffer instead of a file pointer. Since the full buffer must be processed, let's change the return value again to just a success flag. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: extract processing of resource forksPeter Wu1-31/+59
Besides the offset, also read the resource length. This length is now used in the extracted function to verify the end of the resource fork against "count" from the resource fork. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: extract mish block decoding functionalityPeter Wu1-91/+125
Extract the mish block decoder such that this can be used for other formats in the future. A new DmgHeaderState struct is introduced to share state while decoding. The code is kept unchanged as much as possible, a "fail" label is added for example where a simple return would probably do. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-27block/dmg: properly detect the UDIF trailerPeter Wu1-4/+36
DMG files have a variable length with a UDIF trailer at the end of a file. This UDIF trailer is essential as it describes the contents of the image. At the moment however, the start of this trailer is almost always incorrect as bdrv_getlength() returns a multiple of the block size (rounded up). This results in a failure to recognize DMG files, resulting in Invalid argument (EINVAL) errors. As there is no API to retrieve the real file size, look for the magic header in the last two sectors to find the start of this 512-byte UDIF trailer (the "koly" block). The resource fork offset ("info_begin") has its offset adjusted as the initial value of offset does not mean "end of file" anymore, but "begin of UDIF trailer". Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-08-15dmg: Handle failure for potentially large allocationsKevin Wolf1-6/+13
Some code in the block layer makes potentially huge allocations. Failure is not completely unexpected there, so avoid aborting qemu and handle out-of-memory situations gracefully. This patch addresses the allocations in the dmg block driver. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-04-30block: Use correct width in format stringsMax Reitz1-4/+4
Instead of blindly relying on a normal integer having a width of 32 bits (which is a pretty good assumption, but we should not rely on it if there is no need), use the correct format string macros. This does not touch DEBUG output. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-01dmg: prevent chunk buffer overflow (CVE-2014-0145)Stefan Hajnoczi1-6/+33
Both compressed and uncompressed I/O is buffered. dmg_open() calculates the maximum buffer size needed from the metadata in the image file. There is currently a buffer overflow since ->lengths[] is accounted against the maximum compressed buffer size but actually uses the uncompressed buffer: switch (s->types[chunk]) { case 1: /* copy */ ret = bdrv_pread(bs->file, s->offsets[chunk], s->uncompressed_chunk, s->lengths[chunk]); We must account against the maximum uncompressed buffer size for type=1 chunks. This patch fixes the maximum buffer size calculation to take into account the chunk type. It is critical that we update the correct maximum since there are two buffers ->compressed_chunk and ->uncompressed_chunk. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: use uint64_t consistently for sectors and lengthsStefan Hajnoczi1-3/+3
The DMG metadata is stored as uint64_t, so use the same type for sector_num. int was a particularly poor choice since it is only 32-bit and would truncate large values. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: sanitize chunk length and sectorcount (CVE-2014-0145)Stefan Hajnoczi1-0/+24
Chunk length and sectorcount are used for decompression buffers as well as the bdrv_pread() count argument. Ensure that they have reasonable values so neither memory allocation nor conversion from uint64_t to int will cause problems. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: use appropriate types when reading chunksStefan Hajnoczi1-1/+2
Use the right types instead of signed int: size_t new_size; This is a byte count for g_realloc() that is calculated from uint32_t and size_t values. uint32_t chunk_count; Use the same type as s->n_chunks, which is used together with chunk_count. This patch is a cleanup and does not fix bugs. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: drop broken bdrv_pread() loopStefan Hajnoczi1-13/+2
It is not necessary to check errno for EINTR and the block layer does not produce short reads. Therefore we can drop the loop that attempts to read a compressed chunk. The loop is buggy because it incorrectly adds the transferred bytes twice: do { ret = bdrv_pread(...); i += ret; } while (ret >= 0 && ret + i < s->lengths[chunk]); Luckily we can drop the loop completely and perform a single bdrv_pread(). Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: prevent out-of-bounds array access on terminatorStefan Hajnoczi1-1/+1
When a terminator is reached the base for offsets and sectors is stored. The following records that are processed will use this base value. If the first record we encounter is a terminator, then calculating the base values would result in out-of-bounds array accesses. Don't do that. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: coding style and indentation cleanupStefan Hajnoczi1-104/+120
Clean up the mix of tabs and spaces, as well as the coding style violations in block/dmg.c. There are no semantic changes since this patch simply reformats the code. This patch is necessary before we can make meaningful changes to this file, due to the inconsistent formatting and confusing indentation. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-09-12bdrv: Use "Error" for opening imagesMax Reitz1-1/+2
Add an Error ** parameter to BlockDriver.bdrv_open and BlockDriver.bdrv_file_open to allow more specific error messages. Signed-off-by: Max Reitz <mreitz@redhat.com>
2013-03-22block: Make find_image_format safe with NULL filenameKevin Wolf1-3/+10
In order to achieve this, the .bdrv_probe callbacks of all drivers must cope with this. The DMG driver is the only one that bases its decision on the filename and it needs to be changed. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2013-03-15block: Add options QDict to .bdrv_open()Kevin Wolf1-1/+1
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-02-01dmg: Use g_free instead of freeKevin Wolf1-9/+9
The buffers are allocated with g_(re)alloc, so use g_free to free them. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-02-01dmg: Fix bdrv_open() error handlingKevin Wolf1-38/+97
Return -errno instead of -1 on errors and add error checks in some places that didn't have one. Passing things by reference requires more correct typing, replaced a few off_ts therefore - with a 32-bit off_t this is even a fix for truncation bugs. While touching the code, fix even some more memory leaks than in the other drivers... Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2012-12-19misc: move include files to include/qemu/Paolo Bonzini1-2/+2
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-12-19block: move include files to include/block/Paolo Bonzini1-1/+1
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2011-10-21block: take lock around bdrv_read implementationsPaolo Bonzini1-1/+12
This does the first part of the conversion to coroutines, by wrapping bdrv_read implementations to take the mutex. Drivers that implement bdrv_read rather than bdrv_co_readv can then benefit from asynchronous operation (at least if the underlying protocol supports it, which is not the case for raw-win32), even though they still operate with a bounce buffer. raw-win32 does not need the lock, because it cannot yield. nbd also doesn't probably, but better be safe. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-10-21block: add a CoMutex to synchronous read driversPaolo Bonzini1-0/+2
The big conversion of bdrv_read/write to coroutines caused the two homonymous callbacks in BlockDriver to become reentrant. It goes like this: 1) bdrv_read is now called in a coroutine, and calls bdrv_read or bdrv_pread. 2) the nested bdrv_read goes through the fast path in bdrv_rw_co_entry; 3) in the common case when the protocol is file, bdrv_co_do_readv calls bdrv_co_readv_em (and from here goes to bdrv_co_io_em), which yields until the AIO operation is complete; 4) if bdrv_read had been called from a bottom half, the main loop is free to iterate again: a device model or another bottom half can then come and call bdrv_read again. This applies to all four of read/write/flush/discard. It would also apply to is_allocated, but it is not used from within coroutines: besides qemu-img.c and qemu-io.c, which operate synchronously, the only user is the monitor. Copy-on-read will introduce a use in the block layer, and will require converting it. The solution is "simply" to convert all drivers to coroutines! We just need to add a CoMutex that is taken around affected operations. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-08-20Use glib memory allocation and free functionsAnthony Liguori1-7/+7
qemu_malloc/qemu_free no longer exist after this commit. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-05-17dmg: use qemu block APIChristoph Hellwig1-30/+26
Use bdrv_pwrite to access the backing device instead of pread, and convert the driver to implementing the bdrv_open method which gives it an already opened BlockDriverState for the underlying device. Dmg actually does an lseek to a negative offset in the open routine, which we replace with offset arithmetics after doing a bdrv_getlength. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2010-05-17dmg: use preadChristoph Hellwig1-37/+51
Use pread instead of lseek + read in preparation of using the qemu block API. Note that dmg actually uses the implicit file offset a lot in dmg_open, and we had to replace it with an offset variable. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2010-05-17dmg: fix reading of uncompressed chunksChristoph Hellwig1-1/+2
When dmg_read_chunk encounters an uncompressed chunk it currently calls read without any previous adjustment of the file postion. This seems very wrong, and the "reference" implementation in dmg2img does a search to the same offset as done in the various compression cases, so do the same here. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2010-05-03block: Open the underlying image file in generic codeKevin Wolf1-1/+1
Format drivers shouldn't need to bother with things like file names, but rather just get an open BlockDriverState for the underlying protocol. This patch introduces this behaviour for bdrv_open implementation. For protocols which need to access the filename to open their file/device/connection/... a new callback bdrv_file_open is introduced which doesn't get an underlying file opened. For now, also some of the more obscure formats use bdrv_file_open because they open() the file themselves instead of using the block.c functions. They need to be fixed in later patches. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2010-01-11dmg: fix ->open failureChristoph Hellwig1-14/+14
Currently the dmg image format driver simply opens the images as raw if any kind of failure happens. This is contrarty to the behaviour of all other image formats which just return an error and let the block core deal with it. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-07-09Revert "support colon in filenames"Anthony Liguori1-1/+1
This reverts commit 707c0dbc97cddfe8d2441b8259c6c526d99f2dd8. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-06-29support colon in filenamesRam Pai1-1/+1
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name "scsi". This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the "file:" tag is interpreted verbatin. However if "file:" tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb Signed-off-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-05-14Move block drivers into their own directoryAnthony Liguori1-0/+301
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>