|
Subject: isofs: Handle corupted rock-ridge info slightly better. Newsgroups: gmane.linux.kernel.commits.head Date: 2005-03-17 00:13:02 GMT (4 years, 15 weeks, 4 days, 15 hours and 26 minutes ago)
ChangeSet 1.2230, 2005/03/16 16:13:02-08:00, torvalds <at> ppc970.osdl.org
isofs: Handle corupted rock-ridge info slightly better.
Keyword here being 'slightly'. The code is a mess.
rock.c | 21 ++++++++++++++-------
1 files changed, 14 insertions(+), 7 deletions(-)
diff -Nru a/fs/isofs/rock.c b/fs/isofs/rock.c
--- a/fs/isofs/rock.c 2005-03-16 17:09:26 -08:00
+++ b/fs/isofs/rock.c 2005-03-16 17:09:26 -08:00
@@ -53,6 +53,7 @@
if(LEN & 1) LEN++; \
CHR = ((unsigned char *) DE) + LEN; \
LEN = *((unsigned char *) DE) - LEN; \
+ if (LEN<0) LEN=0; \
if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \
{ \
LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \
@@ -103,12 +104,13 @@
struct rock_ridge * rr;
int sig;
- while (len > 1){ /* There may be one byte for padding somewhere */
+ while (len > 2){ /* There may be one byte for padding somewhere */
rr = (struct rock_ridge *) chr;
- if (rr->len == 0) goto out; /* Something got screwed up here */
+ if (rr->len < 3) goto out; /* Something got screwed up here */
sig = isonum_721(chr);
chr += rr->len;
len -= rr->len;
+ if (len < 0) goto out; /* corrupted isofs */
switch(sig){
case SIG('R','R'):
@@ -122,6 +124,7 @@
break;
case SIG('N','M'):
if (truncate) break;
+ if (rr->len < 5) break;
/*
* If the flags are 2 or 4, this indicates '.' or '..'.
* We don't want to do anything with this, because it
@@ -186,12 +189,13 @@
struct rock_ridge * rr;
int rootflag;
- while (len > 1){ /* There may be one byte for padding somewhere */
+ while (len > 2){ /* There may be one byte for padding somewhere */
rr = (struct rock_ridge *) chr;
- if (rr->len == 0) goto out; /* Something got screwed up here */
+ if (rr->len < 3) goto out; /* Something got screwed up here */
sig = isonum_721(chr);
chr += rr->len;
len -= rr->len;
+ if (len < 0) goto out; /* corrupted isofs */
switch(sig){
#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */
@@ -462,7 +466,7 @@
struct rock_ridge *rr;
if (!ISOFS_SB(inode->i_sb)->s_rock)
- panic ("Cannot have symlink with high sierra variant of iso filesystem\n");
+ goto error;
block = ei->i_iget5_block;
lock_kernel();
@@ -487,13 +491,15 @@
SETUP_ROCK_RIDGE(raw_inode, chr, len);
repeat:
- while (len > 1) { /* There may be one byte for padding somewhere */
+ while (len > 2) { /* There may be one byte for padding somewhere */
rr = (struct rock_ridge *) chr;
- if (rr->len == 0)
+ if (rr->len < 3)
goto out; /* Something got screwed up here */
sig = isonum_721(chr);
chr += rr->len;
len -= rr->len;
+ if (len < 0)
+ goto out; /* corrupted isofs */
switch (sig) {
case SIG('R', 'R'):
@@ -543,6 +549,7 @@
fail:
brelse(bh);
unlock_kernel();
+ error:
SetPageError(page);
kunmap(page);
unlock_page(page);
|
|
|