Commit 3725e9dd authored by Jan Harkes's avatar Jan Harkes Committed by Linus Torvalds

fs/coda: fix readlink buffer overflow

Dan Carpenter discovered a buffer overflow in the Coda file system
readlink code.  A userspace file system daemon can return a 4096 byte
result which then triggers a one byte write past the allocated readlink
result buffer.

This does not trigger with an unmodified Coda implementation because Coda
has a 1024 byte limit for symbolic links, however other userspace file
systems using the Coda kernel module could be affected.

Although this is an obvious overflow, I don't think this has to be handled
as too sensitive from a security perspective because the overflow is on
the Coda userspace daemon side which already needs root to open Coda's
kernel device and to mount the file system before we get to the point that
links can be read.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: default avatarJan Harkes <jaharkes@cs.cmu.edu>
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c5595fa2
...@@ -353,7 +353,7 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid, ...@@ -353,7 +353,7 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid,
char *result; char *result;
insize = max_t(unsigned int, insize = max_t(unsigned int,
INSIZE(readlink), OUTSIZE(readlink)+ *length + 1); INSIZE(readlink), OUTSIZE(readlink)+ *length);
UPARG(CODA_READLINK); UPARG(CODA_READLINK);
inp->coda_readlink.VFid = *fid; inp->coda_readlink.VFid = *fid;
...@@ -361,8 +361,8 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid, ...@@ -361,8 +361,8 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid,
error = coda_upcall(coda_vcp(sb), insize, &outsize, inp); error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
if (!error) { if (!error) {
retlen = outp->coda_readlink.count; retlen = outp->coda_readlink.count;
if ( retlen > *length ) if (retlen >= *length)
retlen = *length; retlen = *length - 1;
*length = retlen; *length = retlen;
result = (char *)outp + (long)outp->coda_readlink.data; result = (char *)outp + (long)outp->coda_readlink.data;
memcpy(buffer, result, retlen); memcpy(buffer, result, retlen);
......
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