[PATCH 2.6.26] isofs: fix minor filesystem corruption, take 3

From: Adam Greenblatt
Date: Wed Jul 16 2008 - 05:05:32 EST


Some iso9660 images contain files with rockridge data that is either incorrect or
incompletely parsed. Prior to commit f2966632a134e865db3c819346a1dc7d96e05309
("[PATCH] rock: handle directory overflows") (included with kernel 2.6.13) the
kernel ignored the rockridge data for these files, while still allowing the files
to be accessed under their non-rockridge names. That commit inadvertently changed
things so that files with invalid rockridge data could not be accessed at all.
(I ran across the problem when comparing some old CDs with hard disk copies I had
made long ago under kernel 2.4: a few of the files on the hard disk copies were no
longer visible on the CDs.)

This change reverts to the pre-2.6.13 behavior.

Signed-off-by: Adam Greenblatt <adam.greenblatt@xxxxxxxxx>
---
This patch is functionally identical to the previous one, but correctly formats
the comments and commit description. Please ignore my previous patches, and use
this patch instead. Thanks!
--- linux-2.6.26/fs/isofs/rock.c.orig 2008-07-15 22:49:00.000000000 -1000
+++ linux-2.6.26/fs/isofs/rock.c 2008-07-15 22:50:06.000000000 -1000
@@ -209,6 +209,11 @@ repeat:

while (rs.len > 2) { /* There may be one byte for padding somewhere */
rr = (struct rock_ridge *)rs.chr;
+ /*
+ * Ignore rock ridge info if rr->len is out of range, but
+ * don't return -EIO because that would make the file
+ * invisible.
+ */
if (rr->len < 3)
goto out; /* Something got screwed up here */
sig = isonum_721(rs.chr);
@@ -216,8 +221,12 @@ repeat:
goto eio;
rs.chr += rr->len;
rs.len -= rr->len;
+ /*
+ * As above, just ignore the rock ridge info if rr->len
+ * is bogus.
+ */
if (rs.len < 0)
- goto eio; /* corrupted isofs */
+ goto out; /* Something got screwed up here */

switch (sig) {
case SIG('R', 'R'):
@@ -307,6 +316,11 @@ parse_rock_ridge_inode_internal(struct i
repeat:
while (rs.len > 2) { /* There may be one byte for padding somewhere */
rr = (struct rock_ridge *)rs.chr;
+ /*
+ * Ignore rock ridge info if rr->len is out of range, but
+ * don't return -EIO because that would make the file
+ * invisible.
+ */
if (rr->len < 3)
goto out; /* Something got screwed up here */
sig = isonum_721(rs.chr);
@@ -314,8 +328,12 @@ repeat:
goto eio;
rs.chr += rr->len;
rs.len -= rr->len;
+ /*
+ * As above, just ignore the rock ridge info if rr->len
+ * is bogus.
+ */
if (rs.len < 0)
- goto eio; /* corrupted isofs */
+ goto out; /* Something got screwed up here */

switch (sig) {
#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */

--
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/