提交 8359ffa5 编写于 作者: L Linus Torvalds

Merge tag 'dm-3.12-fix-cve' of git://git.kernel.org/pub/scm/linux/kernel/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
...@@ -269,6 +269,14 @@ static chunk_t area_location(struct pstore *ps, chunk_t area) ...@@ -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); 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 * Read or write a metadata area. Remembering to skip the first
* chunk which holds the header. * chunk which holds the header.
...@@ -502,6 +510,8 @@ static int read_exceptions(struct pstore *ps, ...@@ -502,6 +510,8 @@ static int read_exceptions(struct pstore *ps,
ps->current_area--; ps->current_area--;
skip_metadata(ps);
return 0; return 0;
} }
...@@ -616,8 +626,6 @@ static int persistent_prepare_exception(struct dm_exception_store *store, ...@@ -616,8 +626,6 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct dm_exception *e) struct dm_exception *e)
{ {
struct pstore *ps = get_info(store); 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); sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);
/* Is there enough room ? */ /* Is there enough room ? */
...@@ -630,10 +638,8 @@ static int persistent_prepare_exception(struct dm_exception_store *store, ...@@ -630,10 +638,8 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
* Move onto the next free pending, making sure to take * Move onto the next free pending, making sure to take
* into account the location of the metadata chunks. * 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); atomic_inc(&ps->pending_count);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册