mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
[PATCH] rock.c: handle corrupted directories
The bug in rock.c is that it's totally trusting of the contents of the directories. If the directory says there's a continuation 10000 bytes into this 4k block then we cheerily poke around in memory we don't own and oops. So change rock_continue() to apply various sanity checks, at least ensuring that the offset+length remain within the bounds for the header part of a struct rock_ridge directory entry. Note that the kernel can still overindex the buffer due to the variable size of the rock-ridge directory entries. We cannot check that in rock_continue() unless we go parse the directory entry's signature and work out its size. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
9eb7f2c67c
commit
e595447e17
@ -81,9 +81,22 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
|||||||
static int rock_continue(struct rock_state *rs)
|
static int rock_continue(struct rock_state *rs)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
int blocksize = 1 << rs->inode->i_blkbits;
|
||||||
|
const int min_de_size = offsetof(struct rock_ridge, u);
|
||||||
|
|
||||||
kfree(rs->buffer);
|
kfree(rs->buffer);
|
||||||
rs->buffer = NULL;
|
rs->buffer = NULL;
|
||||||
|
|
||||||
|
if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
|
||||||
|
(unsigned)rs->cont_size > blocksize ||
|
||||||
|
(unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
|
||||||
|
printk(KERN_NOTICE "rock: corrupted directory entry. "
|
||||||
|
"extent=%d, offset=%d, size=%d\n",
|
||||||
|
rs->cont_extent, rs->cont_offset, rs->cont_size);
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (rs->cont_extent) {
|
if (rs->cont_extent) {
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user