Commit 22b45c8c authored by Linus Torvalds's avatar Linus Torvalds

isofs: Handle corupted rock-ridge info slightly better.

Keyword here being 'slightly'. The code is a mess.
parent 3af47cc5
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
if(LEN & 1) LEN++; \ if(LEN & 1) LEN++; \
CHR = ((unsigned char *) DE) + LEN; \ CHR = ((unsigned char *) DE) + LEN; \
LEN = *((unsigned char *) DE) - LEN; \ LEN = *((unsigned char *) DE) - LEN; \
if (LEN<0) LEN=0; \
if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \ if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \
{ \ { \
LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \ LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \
...@@ -103,12 +104,13 @@ int get_rock_ridge_filename(struct iso_directory_record * de, ...@@ -103,12 +104,13 @@ int get_rock_ridge_filename(struct iso_directory_record * de,
struct rock_ridge * rr; struct rock_ridge * rr;
int sig; 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; 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); sig = isonum_721(chr);
chr += rr->len; chr += rr->len;
len -= rr->len; len -= rr->len;
if (len < 0) goto out; /* corrupted isofs */
switch(sig){ switch(sig){
case SIG('R','R'): case SIG('R','R'):
...@@ -122,6 +124,7 @@ int get_rock_ridge_filename(struct iso_directory_record * de, ...@@ -122,6 +124,7 @@ int get_rock_ridge_filename(struct iso_directory_record * de,
break; break;
case SIG('N','M'): case SIG('N','M'):
if (truncate) break; if (truncate) break;
if (rr->len < 5) break;
/* /*
* If the flags are 2 or 4, this indicates '.' or '..'. * If the flags are 2 or 4, this indicates '.' or '..'.
* We don't want to do anything with this, because it * We don't want to do anything with this, because it
...@@ -186,12 +189,13 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, ...@@ -186,12 +189,13 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,
struct rock_ridge * rr; struct rock_ridge * rr;
int rootflag; 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; 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); sig = isonum_721(chr);
chr += rr->len; chr += rr->len;
len -= rr->len; len -= rr->len;
if (len < 0) goto out; /* corrupted isofs */
switch(sig){ switch(sig){
#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */
...@@ -462,7 +466,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) ...@@ -462,7 +466,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
struct rock_ridge *rr; struct rock_ridge *rr;
if (!ISOFS_SB(inode->i_sb)->s_rock) 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; block = ei->i_iget5_block;
lock_kernel(); lock_kernel();
...@@ -487,13 +491,15 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) ...@@ -487,13 +491,15 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
SETUP_ROCK_RIDGE(raw_inode, chr, len); SETUP_ROCK_RIDGE(raw_inode, chr, len);
repeat: 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; rr = (struct rock_ridge *) chr;
if (rr->len == 0) if (rr->len < 3)
goto out; /* Something got screwed up here */ goto out; /* Something got screwed up here */
sig = isonum_721(chr); sig = isonum_721(chr);
chr += rr->len; chr += rr->len;
len -= rr->len; len -= rr->len;
if (len < 0)
goto out; /* corrupted isofs */
switch (sig) { switch (sig) {
case SIG('R', 'R'): case SIG('R', 'R'):
...@@ -543,6 +549,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) ...@@ -543,6 +549,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
fail: fail:
brelse(bh); brelse(bh);
unlock_kernel(); unlock_kernel();
error:
SetPageError(page); SetPageError(page);
kunmap(page); kunmap(page);
unlock_page(page); unlock_page(page);
......
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