diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-08 18:18:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-08 18:18:06 -0400 |
commit | 861b7102b58ea55e171e503c2163efd60a4cc052 (patch) | |
tree | e6e22375644c929057206e8e1e28b512ffcdeb74 | |
parent | 35af25616c6c0c42416545f732d36b2ba7199519 (diff) | |
parent | 7c17705e77b12b20fb8afb7c1b15dcdb126c0c12 (diff) |
Merge branch 'for-3.17' of git://linux-nfs.org/~bfields/linux
Pull nfsd bugfixes from Bruce Fields:
"A couple minor nfsd bugfixes"
* 'for-3.17' of git://linux-nfs.org/~bfields/linux:
lockd: fix rpcbind crash on lockd startup failure
nfsd4: fix rd_dircount enforcement
-rw-r--r-- | fs/lockd/svc.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 14 |
2 files changed, 14 insertions, 4 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 8f27c93f8d2e..ec9e082f9ecd 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -253,13 +253,11 @@ static int lockd_up_net(struct svc_serv *serv, struct net *net) | |||
253 | 253 | ||
254 | error = make_socks(serv, net); | 254 | error = make_socks(serv, net); |
255 | if (error < 0) | 255 | if (error < 0) |
256 | goto err_socks; | 256 | goto err_bind; |
257 | set_grace_period(net); | 257 | set_grace_period(net); |
258 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); | 258 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); |
259 | return 0; | 259 | return 0; |
260 | 260 | ||
261 | err_socks: | ||
262 | svc_rpcb_cleanup(serv, net); | ||
263 | err_bind: | 261 | err_bind: |
264 | ln->nlmsvc_users--; | 262 | ln->nlmsvc_users--; |
265 | return error; | 263 | return error; |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f9821ce6658a..e94457c33ad6 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -2657,6 +2657,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2657 | struct xdr_stream *xdr = cd->xdr; | 2657 | struct xdr_stream *xdr = cd->xdr; |
2658 | int start_offset = xdr->buf->len; | 2658 | int start_offset = xdr->buf->len; |
2659 | int cookie_offset; | 2659 | int cookie_offset; |
2660 | u32 name_and_cookie; | ||
2660 | int entry_bytes; | 2661 | int entry_bytes; |
2661 | __be32 nfserr = nfserr_toosmall; | 2662 | __be32 nfserr = nfserr_toosmall; |
2662 | __be64 wire_offset; | 2663 | __be64 wire_offset; |
@@ -2718,7 +2719,14 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2718 | cd->rd_maxcount -= entry_bytes; | 2719 | cd->rd_maxcount -= entry_bytes; |
2719 | if (!cd->rd_dircount) | 2720 | if (!cd->rd_dircount) |
2720 | goto fail; | 2721 | goto fail; |
2721 | cd->rd_dircount--; | 2722 | /* |
2723 | * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so | ||
2724 | * let's always let through the first entry, at least: | ||
2725 | */ | ||
2726 | name_and_cookie = 4 * XDR_QUADLEN(namlen) + 8; | ||
2727 | if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) | ||
2728 | goto fail; | ||
2729 | cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); | ||
2722 | cd->cookie_offset = cookie_offset; | 2730 | cd->cookie_offset = cookie_offset; |
2723 | skip_entry: | 2731 | skip_entry: |
2724 | cd->common.err = nfs_ok; | 2732 | cd->common.err = nfs_ok; |
@@ -3321,6 +3329,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 | |||
3321 | } | 3329 | } |
3322 | maxcount = min_t(int, maxcount-16, bytes_left); | 3330 | maxcount = min_t(int, maxcount-16, bytes_left); |
3323 | 3331 | ||
3332 | /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */ | ||
3333 | if (!readdir->rd_dircount) | ||
3334 | readdir->rd_dircount = INT_MAX; | ||
3335 | |||
3324 | readdir->xdr = xdr; | 3336 | readdir->xdr = xdr; |
3325 | readdir->rd_maxcount = maxcount; | 3337 | readdir->rd_maxcount = maxcount; |
3326 | readdir->common.err = 0; | 3338 | readdir->common.err = 0; |