block/parallels: Avoid overflows
Change the types of variables in allocate_clusters() to int64_t so we do not have to worry about potential overflows. Add an assertion that our accesses to s->bat[] do not result in a buffer overflow and that the implicit conversion performed when invoking bat_entry_off() does not result in an integer overflow. Coverity-id: 1307776 Signed-off-by: Max Reitz <mreitz@redhat.com> Message-id: 20170331170512.10381-1-mreitz@redhat.com Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
		
							parent
							
								
									f82c5b17ea
								
							
						
					
					
						commit
						86d1bd7098
					
				@ -192,8 +192,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
                                 int nb_sectors, int *pnum)
 | 
			
		||||
{
 | 
			
		||||
    BDRVParallelsState *s = bs->opaque;
 | 
			
		||||
    uint32_t idx, to_allocate, i;
 | 
			
		||||
    int64_t pos, space;
 | 
			
		||||
    int64_t pos, space, idx, to_allocate, i;
 | 
			
		||||
 | 
			
		||||
    pos = block_status(s, sector_num, nb_sectors, pnum);
 | 
			
		||||
    if (pos > 0) {
 | 
			
		||||
@ -201,11 +200,19 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    idx = sector_num / s->tracks;
 | 
			
		||||
    if (idx >= s->bat_size) {
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;
 | 
			
		||||
 | 
			
		||||
    /* This function is called only by parallels_co_writev(), which will never
 | 
			
		||||
     * pass a sector_num at or beyond the end of the image (because the block
 | 
			
		||||
     * layer never passes such a sector_num to that function). Therefore, idx
 | 
			
		||||
     * is always below s->bat_size.
 | 
			
		||||
     * block_status() will limit *pnum so that sector_num + *pnum will not
 | 
			
		||||
     * exceed the image end. Therefore, idx + to_allocate cannot exceed
 | 
			
		||||
     * s->bat_size.
 | 
			
		||||
     * Note that s->bat_size is an unsigned int, therefore idx + to_allocate
 | 
			
		||||
     * will always fit into a uint32_t. */
 | 
			
		||||
    assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
 | 
			
		||||
 | 
			
		||||
    space = to_allocate * s->tracks;
 | 
			
		||||
    if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) {
 | 
			
		||||
        int ret;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user