Commit 1eafbfeb authored by Timo Warns's avatar Timo Warns Committed by Linus Torvalds

Fix corrupted OSF partition table parsing

The kernel automatically evaluates partition tables of storage devices.
The code for evaluating OSF partitions contains a bug that leaks data
from kernel heap memory to userspace for certain corrupted OSF
partitions.

In more detail:

  for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {

iterates from 0 to d_npartitions - 1, where d_npartitions is read from
the partition table without validation and partition is a pointer to an
array of at most 8 d_partitions.

Add the proper and obvious validation.
Signed-off-by: default avatarTimo Warns <warns@pre-sense.de>
Cc: stable@kernel.org
[ Changed the patch trivially to not repeat the whole le16_to_cpu()
  thing, and to use an explicit constant for the magic value '8' ]
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2fbfac4e
...@@ -10,10 +10,13 @@ ...@@ -10,10 +10,13 @@
#include "check.h" #include "check.h"
#include "osf.h" #include "osf.h"
#define MAX_OSF_PARTITIONS 8
int osf_partition(struct parsed_partitions *state) int osf_partition(struct parsed_partitions *state)
{ {
int i; int i;
int slot = 1; int slot = 1;
unsigned int npartitions;
Sector sect; Sector sect;
unsigned char *data; unsigned char *data;
struct disklabel { struct disklabel {
...@@ -45,7 +48,7 @@ int osf_partition(struct parsed_partitions *state) ...@@ -45,7 +48,7 @@ int osf_partition(struct parsed_partitions *state)
u8 p_fstype; u8 p_fstype;
u8 p_frag; u8 p_frag;
__le16 p_cpg; __le16 p_cpg;
} d_partitions[8]; } d_partitions[MAX_OSF_PARTITIONS];
} * label; } * label;
struct d_partition * partition; struct d_partition * partition;
...@@ -63,7 +66,12 @@ int osf_partition(struct parsed_partitions *state) ...@@ -63,7 +66,12 @@ int osf_partition(struct parsed_partitions *state)
put_dev_sector(sect); put_dev_sector(sect);
return 0; return 0;
} }
for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) { npartitions = le16_to_cpu(label->d_npartitions);
if (npartitions > MAX_OSF_PARTITIONS) {
put_dev_sector(sect);
return 0;
}
for (i = 0 ; i < npartitions; i++, partition++) {
if (slot == state->limit) if (slot == state->limit)
break; break;
if (le32_to_cpu(partition->p_size)) if (le32_to_cpu(partition->p_size))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment