[PATCH] PPC64: fix error cases in nvram partition scan

From: Paul Mackerras
Date: Thu Mar 17 2005 - 07:02:45 EST


The NVRAM on pSeries machines and powermacs is structured as a series
of partitions, each of which has a header containing its length
(including the header) and a header checksum. When the checksum was
wrong or the length was zero, we would previously keep trying to scan
through the partitions, possibly looping forever if the length was
zero. This patch changes the behaviour to terminate the scan when a
corrupted partition is found.

Signed-off-by: Utz Bacher <utz.bacher@xxxxxxxxxx>
Signed-off-by: Paul Mackerras <paulus@xxxxxxxxx>

diff -urN linux-2.5/arch/ppc64/kernel/nvram.c test/arch/ppc64/kernel/nvram.c
--- linux-2.5/arch/ppc64/kernel/nvram.c 2005-03-14 18:03:26.000000000 +1100
+++ test/arch/ppc64/kernel/nvram.c 2005-03-14 20:26:55.000000000 +1100
@@ -507,8 +507,8 @@
struct nvram_partition * tmp_part;
unsigned char c_sum;
char * header;
- long size;
int total_size;
+ int err;

if (ppc_md.nvram_size == NULL)
return -ENODEV;
@@ -522,29 +522,37 @@

while (cur_index < total_size) {

- size = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index);
- if (size != NVRAM_HEADER_LEN) {
+ err = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index);
+ if (err != NVRAM_HEADER_LEN) {
printk(KERN_ERR "nvram_scan_partitions: Error parsing "
"nvram partitions\n");
- kfree(header);
- return size;
+ goto out;
}

cur_index -= NVRAM_HEADER_LEN; /* nvram_read will advance us */

memcpy(&phead, header, NVRAM_HEADER_LEN);

+ err = 0;
c_sum = nvram_checksum(&phead);
- if (c_sum != phead.checksum)
- printk(KERN_WARNING "WARNING: nvram partition checksum "
- "was %02x, should be %02x!\n", phead.checksum, c_sum);
-
+ if (c_sum != phead.checksum) {
+ printk(KERN_WARNING "WARNING: nvram partition checksum"
+ " was %02x, should be %02x!\n",
+ phead.checksum, c_sum);
+ printk(KERN_WARNING "Terminating nvram partition scan\n");
+ goto out;
+ }
+ if (!phead.length) {
+ printk(KERN_WARNING "WARNING: nvram corruption "
+ "detected: 0-length partition\n");
+ goto out;
+ }
tmp_part = (struct nvram_partition *)
kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+ err = -ENOMEM;
if (!tmp_part) {
printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n");
- kfree(header);
- return -ENOMEM;
+ goto out;
}

memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN);
@@ -553,9 +561,11 @@

cur_index += phead.length * NVRAM_BLOCK_LEN;
}
+ err = 0;

+ out:
kfree(header);
- return 0;
+ return err;
}

static int __init nvram_init(void)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/