Skip to content

Commit

Permalink
Merge tag 'dm-3.12-fix-cve' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/device-mapper/linux-dm

Pull device-mapper fix from Alasdair Kergon:
 "A patch to avoid data corruption in a device-mapper snapshot.

  This is primarily a data corruption bug that all users of
  device-mapper snapshots will want to fix.  The CVE is due to a data
  leak under specific circumstances if, for example, the snapshot is
  presented to a virtual machine: a block written as data inside the VM
  can get interpreted incorrectly on the host outside the VM as
  metadata, causing the host to provide the VM with access to blocks it
  would not otherwise see.  This is likely to affect few, if any,
  people"

* tag 'dm-3.12-fix-cve' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm snapshot: fix data corruption
  • Loading branch information
Linus Torvalds committed Oct 17, 2013
2 parents 386aa05 + e9c6a18 commit 8359ffa
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions drivers/md/dm-snap-persistent.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ static chunk_t area_location(struct pstore *ps, chunk_t area)
return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area);
}

static void skip_metadata(struct pstore *ps)
{
uint32_t stride = ps->exceptions_per_area + 1;
chunk_t next_free = ps->next_free;
if (sector_div(next_free, stride) == NUM_SNAPSHOT_HDR_CHUNKS)
ps->next_free++;
}

/*
* Read or write a metadata area. Remembering to skip the first
* chunk which holds the header.
Expand Down Expand Up @@ -502,6 +510,8 @@ static int read_exceptions(struct pstore *ps,

ps->current_area--;

skip_metadata(ps);

return 0;
}

Expand Down Expand Up @@ -616,8 +626,6 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct dm_exception *e)
{
struct pstore *ps = get_info(store);
uint32_t stride;
chunk_t next_free;
sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);

/* Is there enough room ? */
Expand All @@ -630,10 +638,8 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
* Move onto the next free pending, making sure to take
* into account the location of the metadata chunks.
*/
stride = (ps->exceptions_per_area + 1);
next_free = ++ps->next_free;
if (sector_div(next_free, stride) == 1)
ps->next_free++;
ps->next_free++;
skip_metadata(ps);

atomic_inc(&ps->pending_count);
return 0;
Expand Down

0 comments on commit 8359ffa

Please sign in to comment.