Skip to content

Commit

Permalink
fs/partitions/ldm.c: fix oops caused by corrupted partition table
Browse files Browse the repository at this point in the history
The kernel automatically evaluates partition tables of storage devices.
The code for evaluating LDM partitions (in fs/partitions/ldm.c) contains
a bug that causes a kernel oops on certain corrupted LDM partitions.
A kernel subsystem seems to crash, because, after the oops, the kernel no
longer recognizes newly connected storage devices.

The patch validates the value of vblk_size.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Timo Warns <warns@pre-sense.de>
Cc: Eugene Teo <eugeneteo@kernel.sg>
Cc: Harvey Harrison <harvey.harrison@gmail.com>
Cc: Richard Russon <rich@flatcap.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Timo Warns authored and Linus Torvalds committed Apr 14, 2011
1 parent c344180 commit c340b1d
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions fs/partitions/ldm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1299,13 +1299,22 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags)

BUG_ON (!data || !frags);

if (size < 2 * VBLK_SIZE_HEAD) {
ldm_error("Value of size is to small.");
return false;
}

group = get_unaligned_be32(data + 0x08);
rec = get_unaligned_be16(data + 0x0C);
num = get_unaligned_be16(data + 0x0E);
if ((num < 1) || (num > 4)) {
ldm_error ("A VBLK claims to have %d parts.", num);
return false;
}
if (rec >= num) {
ldm_error("REC value (%d) exceeds NUM value (%d)", rec, num);
return false;
}

list_for_each (item, frags) {
f = list_entry (item, struct frag, list);
Expand Down Expand Up @@ -1334,10 +1343,9 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags)

f->map |= (1 << rec);

if (num > 0) {
data += VBLK_SIZE_HEAD;
size -= VBLK_SIZE_HEAD;
}
data += VBLK_SIZE_HEAD;
size -= VBLK_SIZE_HEAD;

memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size);

return true;
Expand Down

0 comments on commit c340b1d

Please sign in to comment.