Skip to content

Commit dbc834e

Browse files
Dan Carpenterchucklever
authored andcommitted
NFSD: harden svcxdr_dupstr() and svcxdr_tmpalloc() against integer overflows
These lengths come from xdr_stream_decode_u32() and so we should be a bit careful with them. Use size_add() and struct_size() to avoid integer overflows. Saving size_add()/struct_size() results to a u32 is unsafe because it truncates away the high bits. Also generally storing sizes in longs is safer. Most systems these days use 64 bit CPUs. It's harder for an addition to overflow 64 bits than it is to overflow 32 bits. Also functions like vmalloc() can successfully allocate UINT_MAX bytes, but nothing can allocate ULONG_MAX bytes. Signed-off-by: Dan Carpenter <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 256abd8 commit dbc834e

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

fs/nfsd/nfs4xdr.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ static int zero_clientid(clientid_t *clid)
118118
* operation described in @argp finishes.
119119
*/
120120
static void *
121-
svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
121+
svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, size_t len)
122122
{
123123
struct svcxdr_tmpbuf *tb;
124124

125-
tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
125+
tb = kmalloc(struct_size(tb, buf, len), GFP_KERNEL);
126126
if (!tb)
127127
return NULL;
128128
tb->next = argp->to_free;
@@ -138,9 +138,9 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
138138
* buffer might end on a page boundary.
139139
*/
140140
static char *
141-
svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
141+
svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, size_t len)
142142
{
143-
char *p = svcxdr_tmpalloc(argp, len + 1);
143+
char *p = svcxdr_tmpalloc(argp, size_add(len, 1));
144144

145145
if (!p)
146146
return NULL;
@@ -150,7 +150,7 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
150150
}
151151

152152
static void *
153-
svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, u32 len)
153+
svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, size_t len)
154154
{
155155
__be32 *tmp;
156156

@@ -2146,7 +2146,7 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u)
21462146
*/
21472147
static __be32
21482148
nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
2149-
char **bufp, u32 buflen)
2149+
char **bufp, size_t buflen)
21502150
{
21512151
struct page **pages = xdr->pages;
21522152
struct kvec *head = xdr->head;

0 commit comments

Comments
 (0)