Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

isofs: fix minor filesystem corruption

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@gmail.com>
Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: <stable@kernel.org> [2.6.25.x, 2.6.26.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Adam Greenblatt and committed by
Linus Torvalds
c0a1633b 275c0a8f

+20 -2
+20 -2
fs/isofs/rock.c
··· 209 209 210 210 while (rs.len > 2) { /* There may be one byte for padding somewhere */ 211 211 rr = (struct rock_ridge *)rs.chr; 212 + /* 213 + * Ignore rock ridge info if rr->len is out of range, but 214 + * don't return -EIO because that would make the file 215 + * invisible. 216 + */ 212 217 if (rr->len < 3) 213 218 goto out; /* Something got screwed up here */ 214 219 sig = isonum_721(rs.chr); ··· 221 216 goto eio; 222 217 rs.chr += rr->len; 223 218 rs.len -= rr->len; 219 + /* 220 + * As above, just ignore the rock ridge info if rr->len 221 + * is bogus. 222 + */ 224 223 if (rs.len < 0) 225 - goto eio; /* corrupted isofs */ 224 + goto out; /* Something got screwed up here */ 226 225 227 226 switch (sig) { 228 227 case SIG('R', 'R'): ··· 316 307 repeat: 317 308 while (rs.len > 2) { /* There may be one byte for padding somewhere */ 318 309 rr = (struct rock_ridge *)rs.chr; 310 + /* 311 + * Ignore rock ridge info if rr->len is out of range, but 312 + * don't return -EIO because that would make the file 313 + * invisible. 314 + */ 319 315 if (rr->len < 3) 320 316 goto out; /* Something got screwed up here */ 321 317 sig = isonum_721(rs.chr); ··· 328 314 goto eio; 329 315 rs.chr += rr->len; 330 316 rs.len -= rr->len; 317 + /* 318 + * As above, just ignore the rock ridge info if rr->len 319 + * is bogus. 320 + */ 331 321 if (rs.len < 0) 332 - goto eio; /* corrupted isofs */ 322 + goto out; /* Something got screwed up here */ 333 323 334 324 switch (sig) { 335 325 #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */