Commit de8d4f5d758786a2cbcfa54a6a85ce747e5637e3

Authored by Linus Torvalds

Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  SUNRPC: Fix the NFSv4 and RPCSEC_GSS Kconfig dependencies
  statfs() gives ESTALE error
  NFS: Fix a typo in nfs_sockaddr_match_ipaddr6
  sunrpc: increase MAX_HASHTABLE_BITS to 14
  gss:spkm3 miss returning error to caller when import security context
  gss:krb5 miss returning error to caller when import security context
  Remove incorrect do_vfs_lock message
  SUNRPC: cleanup state-machine ordering
  SUNRPC: Fix a race in rpc_info_open
  SUNRPC: Fix race corrupting rpc upcall
  Fix null dereference in call_allocate

Showing 12 changed files Side-by-side Diff

... ... @@ -63,6 +63,7 @@
63 63 config NFS_V4
64 64 bool "NFS client support for NFS version 4"
65 65 depends on NFS_FS
  66 + select SUNRPC_GSS
66 67 help
67 68 This option enables support for version 4 of the NFS protocol
68 69 (RFC 3530) in the kernel's NFS client.
... ... @@ -275,7 +275,7 @@
275 275 sin1->sin6_scope_id != sin2->sin6_scope_id)
276 276 return 0;
277 277  
278   - return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr);
  278 + return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
279 279 }
280 280 #else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
281 281 static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
... ... @@ -723,10 +723,6 @@
723 723 default:
724 724 BUG();
725 725 }
726   - if (res < 0)
727   - dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager"
728   - " - error %d!\n",
729   - __func__, res);
730 726 return res;
731 727 }
732 728  
... ... @@ -431,7 +431,15 @@
431 431 goto out_err;
432 432  
433 433 error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
  434 + if (unlikely(error == -ESTALE)) {
  435 + struct dentry *pd_dentry;
434 436  
  437 + pd_dentry = dget_parent(dentry);
  438 + if (pd_dentry != NULL) {
  439 + nfs_zap_caches(pd_dentry->d_inode);
  440 + dput(pd_dentry);
  441 + }
  442 + }
435 443 nfs_free_fattr(res.fattr);
436 444 if (error < 0)
437 445 goto out_err;
... ... @@ -69,6 +69,7 @@
69 69 depends on NFSD && PROC_FS && EXPERIMENTAL
70 70 select NFSD_V3
71 71 select FS_POSIX_ACL
  72 + select SUNRPC_GSS
72 73 help
73 74 This option enables support in your system's NFS server for
74 75 version 4 of the NFS protocol (RFC 3530).
include/linux/sunrpc/clnt.h
... ... @@ -30,7 +30,7 @@
30 30 * The high-level client handle
31 31 */
32 32 struct rpc_clnt {
33   - struct kref cl_kref; /* Number of references */
  33 + atomic_t cl_count; /* Number of references */
34 34 struct list_head cl_clients; /* Global list of clients */
35 35 struct list_head cl_tasks; /* List of tasks */
36 36 spinlock_t cl_lock; /* spinlock */
... ... @@ -38,7 +38,7 @@
38 38 static LIST_HEAD(cred_unused);
39 39 static unsigned long number_cred_unused;
40 40  
41   -#define MAX_HASHTABLE_BITS (10)
  41 +#define MAX_HASHTABLE_BITS (14)
42 42 static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
43 43 {
44 44 unsigned long num;
net/sunrpc/auth_gss/auth_gss.c
... ... @@ -745,17 +745,18 @@
745 745 struct rpc_inode *rpci = RPC_I(inode);
746 746 struct gss_upcall_msg *gss_msg;
747 747  
  748 +restart:
748 749 spin_lock(&inode->i_lock);
749   - while (!list_empty(&rpci->in_downcall)) {
  750 + list_for_each_entry(gss_msg, &rpci->in_downcall, list) {
750 751  
751   - gss_msg = list_entry(rpci->in_downcall.next,
752   - struct gss_upcall_msg, list);
  752 + if (!list_empty(&gss_msg->msg.list))
  753 + continue;
753 754 gss_msg->msg.errno = -EPIPE;
754 755 atomic_inc(&gss_msg->count);
755 756 __gss_unhash_msg(gss_msg);
756 757 spin_unlock(&inode->i_lock);
757 758 gss_release_msg(gss_msg);
758   - spin_lock(&inode->i_lock);
  759 + goto restart;
759 760 }
760 761 spin_unlock(&inode->i_lock);
761 762  
net/sunrpc/auth_gss/gss_krb5_mech.c
... ... @@ -237,6 +237,7 @@
237 237 if (!supported_gss_krb5_enctype(alg)) {
238 238 printk(KERN_WARNING "gss_kerberos_mech: unsupported "
239 239 "encryption key algorithm %d\n", alg);
  240 + p = ERR_PTR(-EINVAL);
240 241 goto out_err;
241 242 }
242 243 p = simple_get_netobj(p, end, &key);
243 244  
244 245  
245 246  
... ... @@ -282,15 +283,19 @@
282 283 ctx->enctype = ENCTYPE_DES_CBC_RAW;
283 284  
284 285 ctx->gk5e = get_gss_krb5_enctype(ctx->enctype);
285   - if (ctx->gk5e == NULL)
  286 + if (ctx->gk5e == NULL) {
  287 + p = ERR_PTR(-EINVAL);
286 288 goto out_err;
  289 + }
287 290  
288 291 /* The downcall format was designed before we completely understood
289 292 * the uses of the context fields; so it includes some stuff we
290 293 * just give some minimal sanity-checking, and some we ignore
291 294 * completely (like the next twenty bytes): */
292   - if (unlikely(p + 20 > end || p + 20 < p))
  295 + if (unlikely(p + 20 > end || p + 20 < p)) {
  296 + p = ERR_PTR(-EFAULT);
293 297 goto out_err;
  298 + }
294 299 p += 20;
295 300 p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
296 301 if (IS_ERR(p))
... ... @@ -619,6 +624,7 @@
619 624 if (ctx->seq_send64 != ctx->seq_send) {
620 625 dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__,
621 626 (long unsigned)ctx->seq_send64, ctx->seq_send);
  627 + p = ERR_PTR(-EINVAL);
622 628 goto out_err;
623 629 }
624 630 p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype));
net/sunrpc/auth_gss/gss_spkm3_mech.c
... ... @@ -100,6 +100,7 @@
100 100 if (version != 1) {
101 101 dprintk("RPC: unknown spkm3 token format: "
102 102 "obsolete nfs-utils?\n");
  103 + p = ERR_PTR(-EINVAL);
103 104 goto out_err_free_ctx;
104 105 }
105 106  
106 107  
... ... @@ -135,8 +136,10 @@
135 136 if (IS_ERR(p))
136 137 goto out_err_free_intg_alg;
137 138  
138   - if (p != end)
  139 + if (p != end) {
  140 + p = ERR_PTR(-EFAULT);
139 141 goto out_err_free_intg_key;
  142 + }
140 143  
141 144 ctx_id->internal_ctx_id = ctx;
142 145  
... ... @@ -226,7 +226,7 @@
226 226 goto out_no_principal;
227 227 }
228 228  
229   - kref_init(&clnt->cl_kref);
  229 + atomic_set(&clnt->cl_count, 1);
230 230  
231 231 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
232 232 if (err < 0)
233 233  
... ... @@ -390,14 +390,14 @@
390 390 if (new->cl_principal == NULL)
391 391 goto out_no_principal;
392 392 }
393   - kref_init(&new->cl_kref);
  393 + atomic_set(&new->cl_count, 1);
394 394 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
395 395 if (err != 0)
396 396 goto out_no_path;
397 397 if (new->cl_auth)
398 398 atomic_inc(&new->cl_auth->au_count);
399 399 xprt_get(clnt->cl_xprt);
400   - kref_get(&clnt->cl_kref);
  400 + atomic_inc(&clnt->cl_count);
401 401 rpc_register_client(new);
402 402 rpciod_up();
403 403 return new;
404 404  
... ... @@ -465,10 +465,8 @@
465 465 * Free an RPC client
466 466 */
467 467 static void
468   -rpc_free_client(struct kref *kref)
  468 +rpc_free_client(struct rpc_clnt *clnt)
469 469 {
470   - struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
471   -
472 470 dprintk("RPC: destroying %s client for %s\n",
473 471 clnt->cl_protname, clnt->cl_server);
474 472 if (!IS_ERR(clnt->cl_path.dentry)) {
475 473  
476 474  
... ... @@ -495,12 +493,10 @@
495 493 * Free an RPC client
496 494 */
497 495 static void
498   -rpc_free_auth(struct kref *kref)
  496 +rpc_free_auth(struct rpc_clnt *clnt)
499 497 {
500   - struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
501   -
502 498 if (clnt->cl_auth == NULL) {
503   - rpc_free_client(kref);
  499 + rpc_free_client(clnt);
504 500 return;
505 501 }
506 502  
507 503  
... ... @@ -509,10 +505,11 @@
509 505 * release remaining GSS contexts. This mechanism ensures
510 506 * that it can do so safely.
511 507 */
512   - kref_init(kref);
  508 + atomic_inc(&clnt->cl_count);
513 509 rpcauth_release(clnt->cl_auth);
514 510 clnt->cl_auth = NULL;
515   - kref_put(kref, rpc_free_client);
  511 + if (atomic_dec_and_test(&clnt->cl_count))
  512 + rpc_free_client(clnt);
516 513 }
517 514  
518 515 /*
... ... @@ -525,7 +522,8 @@
525 522  
526 523 if (list_empty(&clnt->cl_tasks))
527 524 wake_up(&destroy_wait);
528   - kref_put(&clnt->cl_kref, rpc_free_auth);
  525 + if (atomic_dec_and_test(&clnt->cl_count))
  526 + rpc_free_auth(clnt);
529 527 }
530 528  
531 529 /**
... ... @@ -588,7 +586,7 @@
588 586 if (clnt != NULL) {
589 587 rpc_task_release_client(task);
590 588 task->tk_client = clnt;
591   - kref_get(&clnt->cl_kref);
  589 + atomic_inc(&clnt->cl_count);
592 590 if (clnt->cl_softrtry)
593 591 task->tk_flags |= RPC_TASK_SOFT;
594 592 /* Add to the client's list of all tasks */
... ... @@ -931,7 +929,7 @@
931 929 task->tk_status = 0;
932 930 if (status >= 0) {
933 931 if (task->tk_rqstp) {
934   - task->tk_action = call_allocate;
  932 + task->tk_action = call_refresh;
935 933 return;
936 934 }
937 935  
938 936  
... ... @@ -966,13 +964,54 @@
966 964 }
967 965  
968 966 /*
969   - * 2. Allocate the buffer. For details, see sched.c:rpc_malloc.
  967 + * 2. Bind and/or refresh the credentials
  968 + */
  969 +static void
  970 +call_refresh(struct rpc_task *task)
  971 +{
  972 + dprint_status(task);
  973 +
  974 + task->tk_action = call_refreshresult;
  975 + task->tk_status = 0;
  976 + task->tk_client->cl_stats->rpcauthrefresh++;
  977 + rpcauth_refreshcred(task);
  978 +}
  979 +
  980 +/*
  981 + * 2a. Process the results of a credential refresh
  982 + */
  983 +static void
  984 +call_refreshresult(struct rpc_task *task)
  985 +{
  986 + int status = task->tk_status;
  987 +
  988 + dprint_status(task);
  989 +
  990 + task->tk_status = 0;
  991 + task->tk_action = call_allocate;
  992 + if (status >= 0 && rpcauth_uptodatecred(task))
  993 + return;
  994 + switch (status) {
  995 + case -EACCES:
  996 + rpc_exit(task, -EACCES);
  997 + return;
  998 + case -ENOMEM:
  999 + rpc_exit(task, -ENOMEM);
  1000 + return;
  1001 + case -ETIMEDOUT:
  1002 + rpc_delay(task, 3*HZ);
  1003 + }
  1004 + task->tk_action = call_refresh;
  1005 +}
  1006 +
  1007 +/*
  1008 + * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc.
970 1009 * (Note: buffer memory is freed in xprt_release).
971 1010 */
972 1011 static void
973 1012 call_allocate(struct rpc_task *task)
974 1013 {
975   - unsigned int slack = task->tk_client->cl_auth->au_cslack;
  1014 + unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack;
976 1015 struct rpc_rqst *req = task->tk_rqstp;
977 1016 struct rpc_xprt *xprt = task->tk_xprt;
978 1017 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
... ... @@ -980,7 +1019,7 @@
980 1019 dprint_status(task);
981 1020  
982 1021 task->tk_status = 0;
983   - task->tk_action = call_refresh;
  1022 + task->tk_action = call_bind;
984 1023  
985 1024 if (req->rq_buffer)
986 1025 return;
... ... @@ -1015,47 +1054,6 @@
1015 1054 }
1016 1055  
1017 1056 rpc_exit(task, -ERESTARTSYS);
1018   -}
1019   -
1020   -/*
1021   - * 2a. Bind and/or refresh the credentials
1022   - */
1023   -static void
1024   -call_refresh(struct rpc_task *task)
1025   -{
1026   - dprint_status(task);
1027   -
1028   - task->tk_action = call_refreshresult;
1029   - task->tk_status = 0;
1030   - task->tk_client->cl_stats->rpcauthrefresh++;
1031   - rpcauth_refreshcred(task);
1032   -}
1033   -
1034   -/*
1035   - * 2b. Process the results of a credential refresh
1036   - */
1037   -static void
1038   -call_refreshresult(struct rpc_task *task)
1039   -{
1040   - int status = task->tk_status;
1041   -
1042   - dprint_status(task);
1043   -
1044   - task->tk_status = 0;
1045   - task->tk_action = call_bind;
1046   - if (status >= 0 && rpcauth_uptodatecred(task))
1047   - return;
1048   - switch (status) {
1049   - case -EACCES:
1050   - rpc_exit(task, -EACCES);
1051   - return;
1052   - case -ENOMEM:
1053   - rpc_exit(task, -ENOMEM);
1054   - return;
1055   - case -ETIMEDOUT:
1056   - rpc_delay(task, 3*HZ);
1057   - }
1058   - task->tk_action = call_refresh;
1059 1057 }
1060 1058  
1061 1059 static inline int
net/sunrpc/rpc_pipe.c
... ... @@ -48,7 +48,7 @@
48 48 return;
49 49 do {
50 50 msg = list_entry(head->next, struct rpc_pipe_msg, list);
51   - list_del(&msg->list);
  51 + list_del_init(&msg->list);
52 52 msg->errno = err;
53 53 destroy_msg(msg);
54 54 } while (!list_empty(head));
... ... @@ -208,7 +208,7 @@
208 208 if (msg != NULL) {
209 209 spin_lock(&inode->i_lock);
210 210 msg->errno = -EAGAIN;
211   - list_del(&msg->list);
  211 + list_del_init(&msg->list);
212 212 spin_unlock(&inode->i_lock);
213 213 rpci->ops->destroy_msg(msg);
214 214 }
... ... @@ -268,7 +268,7 @@
268 268 if (res < 0 || msg->len == msg->copied) {
269 269 filp->private_data = NULL;
270 270 spin_lock(&inode->i_lock);
271   - list_del(&msg->list);
  271 + list_del_init(&msg->list);
272 272 spin_unlock(&inode->i_lock);
273 273 rpci->ops->destroy_msg(msg);
274 274 }
275 275  
276 276  
277 277  
... ... @@ -371,21 +371,23 @@
371 371 static int
372 372 rpc_info_open(struct inode *inode, struct file *file)
373 373 {
374   - struct rpc_clnt *clnt;
  374 + struct rpc_clnt *clnt = NULL;
375 375 int ret = single_open(file, rpc_show_info, NULL);
376 376  
377 377 if (!ret) {
378 378 struct seq_file *m = file->private_data;
379   - mutex_lock(&inode->i_mutex);
380   - clnt = RPC_I(inode)->private;
381   - if (clnt) {
382   - kref_get(&clnt->cl_kref);
  379 +
  380 + spin_lock(&file->f_path.dentry->d_lock);
  381 + if (!d_unhashed(file->f_path.dentry))
  382 + clnt = RPC_I(inode)->private;
  383 + if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {
  384 + spin_unlock(&file->f_path.dentry->d_lock);
383 385 m->private = clnt;
384 386 } else {
  387 + spin_unlock(&file->f_path.dentry->d_lock);
385 388 single_release(inode, file);
386 389 ret = -EINVAL;
387 390 }
388   - mutex_unlock(&inode->i_mutex);
389 391 }
390 392 return ret;
391 393 }