aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/upcall.c
diff options
context:
space:
mode:
authorJan Harkes <jaharkes@cs.cmu.edu>2015-09-09 18:38:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-10 16:29:01 -0400
commit3725e9dd5bef376ab87d41e40c437a6b2a20eb59 (patch)
tree64bb811449dd09f596b2a2b6c5050a72087fe2ec /fs/coda/upcall.c
parentc5595fa2f1ce3c1a74dbd2ddc949257e80d81dc0 (diff)
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: Jan Harkes <jaharkes@cs.cmu.edu> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/coda/upcall.c')
-rw-r--r--fs/coda/upcall.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 9b1ffaa0572e..f6c6c8adbc01 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -353,7 +353,7 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid,
353 char *result; 353 char *result;
354 354
355 insize = max_t(unsigned int, 355 insize = max_t(unsigned int,
356 INSIZE(readlink), OUTSIZE(readlink)+ *length + 1); 356 INSIZE(readlink), OUTSIZE(readlink)+ *length);
357 UPARG(CODA_READLINK); 357 UPARG(CODA_READLINK);
358 358
359 inp->coda_readlink.VFid = *fid; 359 inp->coda_readlink.VFid = *fid;
@@ -361,8 +361,8 @@ int venus_readlink(struct super_block *sb, struct CodaFid *fid,
361 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp); 361 error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
362 if (!error) { 362 if (!error) {
363 retlen = outp->coda_readlink.count; 363 retlen = outp->coda_readlink.count;
364 if ( retlen > *length ) 364 if (retlen >= *length)
365 retlen = *length; 365 retlen = *length - 1;
366 *length = retlen; 366 *length = retlen;
367 result = (char *)outp + (long)outp->coda_readlink.data; 367 result = (char *)outp + (long)outp->coda_readlink.data;
368 memcpy(buffer, result, retlen); 368 memcpy(buffer, result, retlen);