From 7a0df6b947c3c1108f84892cb884564688ebf818 Mon Sep 17 00:00:00 2001 From: Nick Withers Date: Thu, 6 Aug 2015 12:17:41 +1000 Subject: Respect 2^32 - 1 B NFSv2 maximum file size closes #2384 --- cpukit/libfs/src/nfsclient/src/nfs.c | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c index 270a9fa7a4..17a726dfdf 100644 --- a/cpukit/libfs/src/nfsclient/src/nfs.c +++ b/cpukit/libfs/src/nfsclient/src/nfs.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -2451,6 +2452,20 @@ static ssize_t nfs_file_read( uint32_t offset = iop->offset; char *in = buffer; + if (iop->offset < 0) { + errno = EINVAL; + return -1; + } + + if ((uintmax_t) iop->offset >= UINT32_MAX) { + errno = EFBIG; + return -1; + } + + if (count > UINT32_MAX - offset) { + count = UINT32_MAX - offset; + } + do { size_t chunk = count <= NFS_MAXDATA ? count : NFS_MAXDATA; ssize_t done = nfs_file_read_chunk(node, offset, in, chunk); @@ -2550,15 +2565,32 @@ Nfs nfs = node->nfs; count = NFS_MAXDATA; - SERP_ARGS(node).writearg.beginoffset = UINT32_C(0xdeadbeef); + SERP_ARGS(node).writearg.beginoffset = UINT32_C(0xdeadbeef); if ( LIBIO_FLAGS_APPEND & iop->flags ) { if ( updateAttr(node, 0) ) { return -1; } - SERP_ARGS(node).writearg.offset = SERP_ATTR(node).size; + if (SERP_ATTR(node).size >= UINT32_MAX) { + errno = EFBIG; + return -1; + } + SERP_ARGS(node).writearg.offset = SERP_ATTR(node).size; } else { - SERP_ARGS(node).writearg.offset = iop->offset; + if (iop->offset < 0) { + errno = EINVAL; + return -1; + } + if ((uintmax_t) iop->offset >= UINT32_MAX) { + errno = EFBIG; + return -1; + } + SERP_ARGS(node).writearg.offset = iop->offset; } + + if (count > UINT32_MAX - SERP_ARGS(node).writearg.offset) { + count = UINT32_MAX - SERP_ARGS(node).writearg.offset; + } + SERP_ARGS(node).writearg.totalcount = UINT32_C(0xdeadbeef); SERP_ARGS(node).writearg.data.data_len = count; SERP_ARGS(node).writearg.data.data_val = (void*)buffer; @@ -2817,6 +2849,16 @@ static int nfs_file_ftruncate( { sattr arg; + if (length < 0) { + errno = EINVAL; + return -1; + } + + if ((uintmax_t) length > UINT32_MAX) { + errno = EFBIG; + return -1; + } + arg.size = length; /* must not modify any other attribute; if we are not the owner * of the file or directory but only have write access changing -- cgit v1.2.3