aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-09-02 13:58:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-09-02 13:58:11 -0400
commite77295dc9e6b52281ae85af4068f13752524e9f4 (patch)
treefca6b723f6c91f2af79b28f05c05e114720fbe66
parent1136cf11066a32d4ac2a476dac302858d763703d (diff)
parent91b80969ba466ba4b915a4a1d03add8c297add3f (diff)
Merge branch 'for-2.6.27' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.27' of git://linux-nfs.org/~bfields/linux: nfsd: fix buffer overrun decoding NFSv4 acl sunrpc: fix possible overrun on read of /proc/sys/sunrpc/transports nfsd: fix compound state allocation error handling svcrdma: Fix race between svc_rdma_recvfrom thread and the dto_tasklet
-rw-r--r--fs/nfsd/nfs4acl.c2
-rw-r--r--fs/nfsd/nfs4proc.c12
-rw-r--r--include/linux/sunrpc/svc_rdma.h1
-rw-r--r--net/sunrpc/sysctl.c18
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c8
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c5
6 files changed, 17 insertions, 29 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index b6ed38380ab8..54b8b4140c8f 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -443,7 +443,7 @@ init_state(struct posix_acl_state *state, int cnt)
443 * enough space for either: 443 * enough space for either:
444 */ 444 */
445 alloc = sizeof(struct posix_ace_state_array) 445 alloc = sizeof(struct posix_ace_state_array)
446 + cnt*sizeof(struct posix_ace_state); 446 + cnt*sizeof(struct posix_user_ace_state);
447 state->users = kzalloc(alloc, GFP_KERNEL); 447 state->users = kzalloc(alloc, GFP_KERNEL);
448 if (!state->users) 448 if (!state->users)
449 return -ENOMEM; 449 return -ENOMEM;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 2e51adac65de..e5b51ffafc6c 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -867,11 +867,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
867 int slack_bytes; 867 int slack_bytes;
868 __be32 status; 868 __be32 status;
869 869
870 status = nfserr_resource;
871 cstate = cstate_alloc();
872 if (cstate == NULL)
873 goto out;
874
875 resp->xbuf = &rqstp->rq_res; 870 resp->xbuf = &rqstp->rq_res;
876 resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; 871 resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len;
877 resp->tagp = resp->p; 872 resp->tagp = resp->p;
@@ -890,6 +885,11 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
890 if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION) 885 if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
891 goto out; 886 goto out;
892 887
888 status = nfserr_resource;
889 cstate = cstate_alloc();
890 if (cstate == NULL)
891 goto out;
892
893 status = nfs_ok; 893 status = nfs_ok;
894 while (!status && resp->opcnt < args->opcnt) { 894 while (!status && resp->opcnt < args->opcnt) {
895 op = &args->ops[resp->opcnt++]; 895 op = &args->ops[resp->opcnt++];
@@ -957,9 +957,9 @@ encode_op:
957 nfsd4_increment_op_stats(op->opnum); 957 nfsd4_increment_op_stats(op->opnum);
958 } 958 }
959 959
960 cstate_free(cstate);
960out: 961out:
961 nfsd4_release_compoundargs(args); 962 nfsd4_release_compoundargs(args);
962 cstate_free(cstate);
963 dprintk("nfsv4 compound returned %d\n", ntohl(status)); 963 dprintk("nfsv4 compound returned %d\n", ntohl(status));
964 return status; 964 return status;
965} 965}
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index ef2e3a20bf3b..dc05b54bd3a3 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -143,7 +143,6 @@ struct svcxprt_rdma {
143 unsigned long sc_flags; 143 unsigned long sc_flags;
144 struct list_head sc_dto_q; /* DTO tasklet I/O pending Q */ 144 struct list_head sc_dto_q; /* DTO tasklet I/O pending Q */
145 struct list_head sc_read_complete_q; 145 struct list_head sc_read_complete_q;
146 spinlock_t sc_read_complete_lock;
147 struct work_struct sc_work; 146 struct work_struct sc_work;
148}; 147};
149/* sc_flags */ 148/* sc_flags */
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 0f8c439b848a..5231f7aaac0e 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -60,24 +60,14 @@ static int proc_do_xprt(ctl_table *table, int write, struct file *file,
60 void __user *buffer, size_t *lenp, loff_t *ppos) 60 void __user *buffer, size_t *lenp, loff_t *ppos)
61{ 61{
62 char tmpbuf[256]; 62 char tmpbuf[256];
63 int len; 63 size_t len;
64
64 if ((*ppos && !write) || !*lenp) { 65 if ((*ppos && !write) || !*lenp) {
65 *lenp = 0; 66 *lenp = 0;
66 return 0; 67 return 0;
67 } 68 }
68 if (write) 69 len = svc_print_xprts(tmpbuf, sizeof(tmpbuf));
69 return -EINVAL; 70 return simple_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len);
70 else {
71 len = svc_print_xprts(tmpbuf, sizeof(tmpbuf));
72 if (!access_ok(VERIFY_WRITE, buffer, len))
73 return -EFAULT;
74
75 if (__copy_to_user(buffer, tmpbuf, len))
76 return -EFAULT;
77 }
78 *lenp -= len;
79 *ppos += len;
80 return 0;
81} 71}
82 72
83static int 73static int
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index b4b17f44cb29..74de31a06616 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -443,18 +443,18 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
443 443
444 dprintk("svcrdma: rqstp=%p\n", rqstp); 444 dprintk("svcrdma: rqstp=%p\n", rqstp);
445 445
446 spin_lock_bh(&rdma_xprt->sc_read_complete_lock); 446 spin_lock_bh(&rdma_xprt->sc_rq_dto_lock);
447 if (!list_empty(&rdma_xprt->sc_read_complete_q)) { 447 if (!list_empty(&rdma_xprt->sc_read_complete_q)) {
448 ctxt = list_entry(rdma_xprt->sc_read_complete_q.next, 448 ctxt = list_entry(rdma_xprt->sc_read_complete_q.next,
449 struct svc_rdma_op_ctxt, 449 struct svc_rdma_op_ctxt,
450 dto_q); 450 dto_q);
451 list_del_init(&ctxt->dto_q); 451 list_del_init(&ctxt->dto_q);
452 } 452 }
453 spin_unlock_bh(&rdma_xprt->sc_read_complete_lock); 453 if (ctxt) {
454 if (ctxt) 454 spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock);
455 return rdma_read_complete(rqstp, ctxt); 455 return rdma_read_complete(rqstp, ctxt);
456 }
456 457
457 spin_lock_bh(&rdma_xprt->sc_rq_dto_lock);
458 if (!list_empty(&rdma_xprt->sc_rq_dto_q)) { 458 if (!list_empty(&rdma_xprt->sc_rq_dto_q)) {
459 ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next, 459 ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next,
460 struct svc_rdma_op_ctxt, 460 struct svc_rdma_op_ctxt,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 19ddc382b777..900cb69728c6 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -359,11 +359,11 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt)
359 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) { 359 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
360 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr; 360 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
361 BUG_ON(!read_hdr); 361 BUG_ON(!read_hdr);
362 spin_lock_bh(&xprt->sc_rq_dto_lock);
362 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); 363 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
363 spin_lock_bh(&xprt->sc_read_complete_lock);
364 list_add_tail(&read_hdr->dto_q, 364 list_add_tail(&read_hdr->dto_q,
365 &xprt->sc_read_complete_q); 365 &xprt->sc_read_complete_q);
366 spin_unlock_bh(&xprt->sc_read_complete_lock); 366 spin_unlock_bh(&xprt->sc_rq_dto_lock);
367 svc_xprt_enqueue(&xprt->sc_xprt); 367 svc_xprt_enqueue(&xprt->sc_xprt);
368 } 368 }
369 svc_rdma_put_context(ctxt, 0); 369 svc_rdma_put_context(ctxt, 0);
@@ -428,7 +428,6 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
428 init_waitqueue_head(&cma_xprt->sc_send_wait); 428 init_waitqueue_head(&cma_xprt->sc_send_wait);
429 429
430 spin_lock_init(&cma_xprt->sc_lock); 430 spin_lock_init(&cma_xprt->sc_lock);
431 spin_lock_init(&cma_xprt->sc_read_complete_lock);
432 spin_lock_init(&cma_xprt->sc_rq_dto_lock); 431 spin_lock_init(&cma_xprt->sc_rq_dto_lock);
433 432
434 cma_xprt->sc_ord = svcrdma_ord; 433 cma_xprt->sc_ord = svcrdma_ord;