aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-02-11 13:56:54 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-02-11 13:56:54 -0500
commit628356791b04ea988fee070f66a748a823d001bb (patch)
treefa4606e35088798f303b0103b1dedae2a446beec /net
parent06ea0bfe6e6043cb56a78935a19f6f8ebc636226 (diff)
SUNRPC: Fix potential memory scribble in xprt_free_bc_request()
The call to xprt_free_allocation() will call list_del() on req->rq_bc_pa_list, which is not attached to a list. This patch moves the list_del() out of xprt_free_allocation() and into those callers that need it. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/backchannel_rqst.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 890a29912d5a..e860d4f7ed2a 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -64,7 +64,6 @@ static void xprt_free_allocation(struct rpc_rqst *req)
64 free_page((unsigned long)xbufp->head[0].iov_base); 64 free_page((unsigned long)xbufp->head[0].iov_base);
65 xbufp = &req->rq_snd_buf; 65 xbufp = &req->rq_snd_buf;
66 free_page((unsigned long)xbufp->head[0].iov_base); 66 free_page((unsigned long)xbufp->head[0].iov_base);
67 list_del(&req->rq_bc_pa_list);
68 kfree(req); 67 kfree(req);
69} 68}
70 69
@@ -168,8 +167,10 @@ out_free:
168 /* 167 /*
169 * Memory allocation failed, free the temporary list 168 * Memory allocation failed, free the temporary list
170 */ 169 */
171 list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) 170 list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) {
171 list_del(&req->rq_bc_pa_list);
172 xprt_free_allocation(req); 172 xprt_free_allocation(req);
173 }
173 174
174 dprintk("RPC: setup backchannel transport failed\n"); 175 dprintk("RPC: setup backchannel transport failed\n");
175 return -ENOMEM; 176 return -ENOMEM;
@@ -198,6 +199,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs)
198 xprt_dec_alloc_count(xprt, max_reqs); 199 xprt_dec_alloc_count(xprt, max_reqs);
199 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { 200 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
200 dprintk("RPC: req=%p\n", req); 201 dprintk("RPC: req=%p\n", req);
202 list_del(&req->rq_bc_pa_list);
201 xprt_free_allocation(req); 203 xprt_free_allocation(req);
202 if (--max_reqs == 0) 204 if (--max_reqs == 0)
203 break; 205 break;