aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-10 12:28:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-10 12:28:55 -0400
commit2dbd3cac87250a0d44e07acc86c4224a08522709 (patch)
tree4f31fdf50bfe64616aca1c4e2405930fd5b15e84
parenta77c005887a6d6f318117176791efa0ef7fcca80 (diff)
parent7255e716b1757dc10fa5e3a4d2eaab303ff9f7b6 (diff)
Merge branch 'for-3.10' of git://linux-nfs.org/~bfields/linux
Pull nfsd fixes from Bruce Fields: "Small fixes for two bugs and two warnings" * 'for-3.10' of git://linux-nfs.org/~bfields/linux: nfsd: fix oops when legacy_recdir_name_error is passed a -ENOENT error SUNRPC: fix decoding of optional gss-proxy xdr fields SUNRPC: Refactor gssx_dec_option_array() to kill uninitialized warning nfsd4: don't allow owner override on 4.1 CLAIM_FH opens
-rw-r--r--fs/nfsd/nfs4proc.c15
-rw-r--r--fs/nfsd/nfs4recover.c12
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.c58
3 files changed, 48 insertions, 37 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 8ae5abfe6ba2..27d74a294515 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -279,6 +279,7 @@ do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, str
279{ 279{
280 struct svc_fh *current_fh = &cstate->current_fh; 280 struct svc_fh *current_fh = &cstate->current_fh;
281 __be32 status; 281 __be32 status;
282 int accmode = 0;
282 283
283 /* We don't know the target directory, and therefore can not 284 /* We don't know the target directory, and therefore can not
284 * set the change info 285 * set the change info
@@ -290,9 +291,19 @@ do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, str
290 291
291 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 292 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
292 (open->op_iattr.ia_size == 0); 293 (open->op_iattr.ia_size == 0);
294 /*
295 * In the delegation case, the client is telling us about an
296 * open that it *already* performed locally, some time ago. We
297 * should let it succeed now if possible.
298 *
299 * In the case of a CLAIM_FH open, on the other hand, the client
300 * may be counting on us to enforce permissions (the Linux 4.1
301 * client uses this for normal opens, for example).
302 */
303 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH)
304 accmode = NFSD_MAY_OWNER_OVERRIDE;
293 305
294 status = do_open_permission(rqstp, current_fh, open, 306 status = do_open_permission(rqstp, current_fh, open, accmode);
295 NFSD_MAY_OWNER_OVERRIDE);
296 307
297 return status; 308 return status;
298} 309}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 899ca26dd194..4e9a21db867a 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -146,7 +146,7 @@ out_no_tfm:
146 * then disable recovery tracking. 146 * then disable recovery tracking.
147 */ 147 */
148static void 148static void
149legacy_recdir_name_error(int error) 149legacy_recdir_name_error(struct nfs4_client *clp, int error)
150{ 150{
151 printk(KERN_ERR "NFSD: unable to generate recoverydir " 151 printk(KERN_ERR "NFSD: unable to generate recoverydir "
152 "name (%d).\n", error); 152 "name (%d).\n", error);
@@ -159,9 +159,7 @@ legacy_recdir_name_error(int error)
159 if (error == -ENOENT) { 159 if (error == -ENOENT) {
160 printk(KERN_ERR "NFSD: disabling legacy clientid tracking. " 160 printk(KERN_ERR "NFSD: disabling legacy clientid tracking. "
161 "Reboot recovery will not function correctly!\n"); 161 "Reboot recovery will not function correctly!\n");
162 162 nfsd4_client_tracking_exit(clp->net);
163 /* the argument is ignored by the legacy exit function */
164 nfsd4_client_tracking_exit(NULL);
165 } 163 }
166} 164}
167 165
@@ -184,7 +182,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
184 182
185 status = nfs4_make_rec_clidname(dname, &clp->cl_name); 183 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
186 if (status) 184 if (status)
187 return legacy_recdir_name_error(status); 185 return legacy_recdir_name_error(clp, status);
188 186
189 status = nfs4_save_creds(&original_cred); 187 status = nfs4_save_creds(&original_cred);
190 if (status < 0) 188 if (status < 0)
@@ -341,7 +339,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
341 339
342 status = nfs4_make_rec_clidname(dname, &clp->cl_name); 340 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
343 if (status) 341 if (status)
344 return legacy_recdir_name_error(status); 342 return legacy_recdir_name_error(clp, status);
345 343
346 status = mnt_want_write_file(nn->rec_file); 344 status = mnt_want_write_file(nn->rec_file);
347 if (status) 345 if (status)
@@ -601,7 +599,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
601 599
602 status = nfs4_make_rec_clidname(dname, &clp->cl_name); 600 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
603 if (status) { 601 if (status) {
604 legacy_recdir_name_error(status); 602 legacy_recdir_name_error(clp, status);
605 return status; 603 return status;
606 } 604 }
607 605
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index 5c4c61d527e2..357f613df7ff 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -21,16 +21,6 @@
21#include <linux/sunrpc/svcauth.h> 21#include <linux/sunrpc/svcauth.h>
22#include "gss_rpc_xdr.h" 22#include "gss_rpc_xdr.h"
23 23
24static bool gssx_check_pointer(struct xdr_stream *xdr)
25{
26 __be32 *p;
27
28 p = xdr_reserve_space(xdr, 4);
29 if (unlikely(p == NULL))
30 return -ENOSPC;
31 return *p?true:false;
32}
33
34static int gssx_enc_bool(struct xdr_stream *xdr, int v) 24static int gssx_enc_bool(struct xdr_stream *xdr, int v)
35{ 25{
36 __be32 *p; 26 __be32 *p;
@@ -264,25 +254,27 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
264 if (unlikely(p == NULL)) 254 if (unlikely(p == NULL))
265 return -ENOSPC; 255 return -ENOSPC;
266 count = be32_to_cpup(p++); 256 count = be32_to_cpup(p++);
267 if (count != 0) { 257 if (!count)
268 /* we recognize only 1 currently: CREDS_VALUE */ 258 return 0;
269 oa->count = 1;
270 259
271 oa->data = kmalloc(sizeof(struct gssx_option), GFP_KERNEL); 260 /* we recognize only 1 currently: CREDS_VALUE */
272 if (!oa->data) 261 oa->count = 1;
273 return -ENOMEM;
274 262
275 creds = kmalloc(sizeof(struct svc_cred), GFP_KERNEL); 263 oa->data = kmalloc(sizeof(struct gssx_option), GFP_KERNEL);
276 if (!creds) { 264 if (!oa->data)
277 kfree(oa->data); 265 return -ENOMEM;
278 return -ENOMEM;
279 }
280 266
281 oa->data[0].option.data = CREDS_VALUE; 267 creds = kmalloc(sizeof(struct svc_cred), GFP_KERNEL);
282 oa->data[0].option.len = sizeof(CREDS_VALUE); 268 if (!creds) {
283 oa->data[0].value.data = (void *)creds; 269 kfree(oa->data);
284 oa->data[0].value.len = 0; 270 return -ENOMEM;
285 } 271 }
272
273 oa->data[0].option.data = CREDS_VALUE;
274 oa->data[0].option.len = sizeof(CREDS_VALUE);
275 oa->data[0].value.data = (void *)creds;
276 oa->data[0].value.len = 0;
277
286 for (i = 0; i < count; i++) { 278 for (i = 0; i < count; i++) {
287 gssx_buffer dummy = { 0, NULL }; 279 gssx_buffer dummy = { 0, NULL };
288 u32 length; 280 u32 length;
@@ -800,6 +792,7 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
800 struct xdr_stream *xdr, 792 struct xdr_stream *xdr,
801 struct gssx_res_accept_sec_context *res) 793 struct gssx_res_accept_sec_context *res)
802{ 794{
795 u32 value_follows;
803 int err; 796 int err;
804 797
805 /* res->status */ 798 /* res->status */
@@ -808,7 +801,10 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
808 return err; 801 return err;
809 802
810 /* res->context_handle */ 803 /* res->context_handle */
811 if (gssx_check_pointer(xdr)) { 804 err = gssx_dec_bool(xdr, &value_follows);
805 if (err)
806 return err;
807 if (value_follows) {
812 err = gssx_dec_ctx(xdr, res->context_handle); 808 err = gssx_dec_ctx(xdr, res->context_handle);
813 if (err) 809 if (err)
814 return err; 810 return err;
@@ -817,7 +813,10 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
817 } 813 }
818 814
819 /* res->output_token */ 815 /* res->output_token */
820 if (gssx_check_pointer(xdr)) { 816 err = gssx_dec_bool(xdr, &value_follows);
817 if (err)
818 return err;
819 if (value_follows) {
821 err = gssx_dec_buffer(xdr, res->output_token); 820 err = gssx_dec_buffer(xdr, res->output_token);
822 if (err) 821 if (err)
823 return err; 822 return err;
@@ -826,7 +825,10 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
826 } 825 }
827 826
828 /* res->delegated_cred_handle */ 827 /* res->delegated_cred_handle */
829 if (gssx_check_pointer(xdr)) { 828 err = gssx_dec_bool(xdr, &value_follows);
829 if (err)
830 return err;
831 if (value_follows) {
830 /* we do not support upcall servers sending this data. */ 832 /* we do not support upcall servers sending this data. */
831 return -EINVAL; 833 return -EINVAL;
832 } 834 }