2017-10-29 03:46:24 -04:00
|
|
|
From 212c4d33ca83e2144064fe9c2911607fbed5386f Mon Sep 17 00:00:00 2001
|
2017-10-29 01:48:53 -04:00
|
|
|
From: Jan Kara <jack@suse.cz>
|
|
|
|
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
2017-10-29 03:46:24 -04:00
|
|
|
Subject: isofs: Fix infinite looping over CE entries
|
|
|
|
|
|
|
|
commit f54e18f1b831c92f6512d2eedb224cd63d607d3d upstream.
|
2017-10-29 01:48:53 -04:00
|
|
|
|
|
|
|
Rock Ridge extensions define so called Continuation Entries (CE) which
|
|
|
|
define where is further space with Rock Ridge data. Corrupted isofs
|
|
|
|
image can contain arbitrarily long chain of these, including a one
|
|
|
|
containing loop and thus causing kernel to end in an infinite loop when
|
|
|
|
traversing these entries.
|
|
|
|
|
|
|
|
Limit the traversal to 32 entries which should be more than enough space
|
|
|
|
to store all the Rock Ridge data.
|
|
|
|
|
|
|
|
Reported-by: P J P <ppandit@redhat.com>
|
|
|
|
Signed-off-by: Jan Kara <jack@suse.cz>
|
2017-10-29 03:46:24 -04:00
|
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
2017-10-29 01:48:53 -04:00
|
|
|
---
|
|
|
|
fs/isofs/rock.c | 6 ++++++
|
|
|
|
1 file changed, 6 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
2017-10-29 03:46:24 -04:00
|
|
|
index ee62cc0..26859de 100644
|
2017-10-29 01:48:53 -04:00
|
|
|
--- a/fs/isofs/rock.c
|
|
|
|
+++ b/fs/isofs/rock.c
|
|
|
|
@@ -30,6 +30,7 @@ struct rock_state {
|
|
|
|
int cont_size;
|
|
|
|
int cont_extent;
|
|
|
|
int cont_offset;
|
|
|
|
+ int cont_loops;
|
|
|
|
struct inode *inode;
|
|
|
|
};
|
|
|
|
|
|
|
|
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
|
|
|
rs->inode = inode;
|
|
|
|
}
|
|
|
|
|
|
|
|
+/* Maximum number of Rock Ridge continuation entries */
|
|
|
|
+#define RR_MAX_CE_ENTRIES 32
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* Returns 0 if the caller should continue scanning, 1 if the scan must end
|
|
|
|
* and -ve on error.
|
|
|
|
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ret = -EIO;
|
|
|
|
+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
|
|
|
|
+ goto out;
|
|
|
|
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
|
|
|
if (bh) {
|
|
|
|
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
2017-10-29 03:46:24 -04:00
|
|
|
--
|
|
|
|
cgit v1.1
|
|
|
|
|