]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
fix memory corruption from misinterpreted bad_inode_ops return values (CVE-2006-5753)
authorEric Sandeen <sandeen@redhat.com>
Thu, 22 Feb 2007 16:09:19 +0000 (11:09 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 3 Mar 2007 00:32:45 +0000 (16:32 -0800)
commitcf4e6070ffc2d348671706336fbd9bec6bcc1b34
tree3f0d0fb6cd6a0934a7927d29cacfd60047babf87
parent8658e1a8a8d97810287f8a8daef91e42aeb36cb8
fix memory corruption from misinterpreted bad_inode_ops return values (CVE-2006-5753)

CVE-2006-5753 is for a case where an inode can be marked bad, switching
the ops to bad_inode_ops, which are all connected as:

static int return_EIO(void)
{
        return -EIO;
}

#define EIO_ERROR ((void *) (return_EIO))

static struct inode_operations bad_inode_ops =
{
        .create         = bad_inode_create
...etc...

The problem here is that the void cast causes return types to not be
promoted, and for ops such as listxattr which expect more than 32 bits of
return value, the 32-bit -EIO is interpreted as a large positive 64-bit
number, i.e. 0x00000000fffffffa instead of 0xfffffffa.

This goes particularly badly when the return value is taken as a number of
bytes to copy into, say, a user's buffer for example...

I originally had coded up the fix by creating a return_EIO_<TYPE> macro
for each return type, like this:

static int return_EIO_int(void)
{
return -EIO;
}
#define EIO_ERROR_INT ((void *) (return_EIO_int))

static struct inode_operations bad_inode_ops =
{
.create = EIO_ERROR_INT,
...etc...

but Al felt that it was probably better to create an EIO-returner for each
actual op signature.  Since so few ops share a signature, I just went ahead
& created an EIO function for each individual file & inode op that returns
a value.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/bad_inode.c