aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/netns.h5
-rw-r--r--fs/nfsd/nfs4state.c38
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c13
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c82
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c21
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_backchannel.c12
-rw-r--r--net/sunrpc/xprtsock.c1
7 files changed, 106 insertions, 66 deletions
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index b10d557f9c9e..ee36efd5aece 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -84,6 +84,8 @@ struct nfsd_net {
84 struct list_head client_lru; 84 struct list_head client_lru;
85 struct list_head close_lru; 85 struct list_head close_lru;
86 struct list_head del_recall_lru; 86 struct list_head del_recall_lru;
87
88 /* protected by blocked_locks_lock */
87 struct list_head blocked_locks_lru; 89 struct list_head blocked_locks_lru;
88 90
89 struct delayed_work laundromat_work; 91 struct delayed_work laundromat_work;
@@ -91,6 +93,9 @@ struct nfsd_net {
91 /* client_lock protects the client lru list and session hash table */ 93 /* client_lock protects the client lru list and session hash table */
92 spinlock_t client_lock; 94 spinlock_t client_lock;
93 95
96 /* protects blocked_locks_lru */
97 spinlock_t blocked_locks_lock;
98
94 struct file *rec_file; 99 struct file *rec_file;
95 bool in_grace; 100 bool in_grace;
96 const struct nfsd4_client_tracking_ops *client_tracking_ops; 101 const struct nfsd4_client_tracking_ops *client_tracking_ops;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9752beb78659..4b4beaaa4eaa 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -217,7 +217,7 @@ find_blocked_lock(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
217{ 217{
218 struct nfsd4_blocked_lock *cur, *found = NULL; 218 struct nfsd4_blocked_lock *cur, *found = NULL;
219 219
220 spin_lock(&nn->client_lock); 220 spin_lock(&nn->blocked_locks_lock);
221 list_for_each_entry(cur, &lo->lo_blocked, nbl_list) { 221 list_for_each_entry(cur, &lo->lo_blocked, nbl_list) {
222 if (fh_match(fh, &cur->nbl_fh)) { 222 if (fh_match(fh, &cur->nbl_fh)) {
223 list_del_init(&cur->nbl_list); 223 list_del_init(&cur->nbl_list);
@@ -226,7 +226,7 @@ find_blocked_lock(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
226 break; 226 break;
227 } 227 }
228 } 228 }
229 spin_unlock(&nn->client_lock); 229 spin_unlock(&nn->blocked_locks_lock);
230 if (found) 230 if (found)
231 posix_unblock_lock(&found->nbl_lock); 231 posix_unblock_lock(&found->nbl_lock);
232 return found; 232 return found;
@@ -1227,9 +1227,7 @@ static void put_ol_stateid_locked(struct nfs4_ol_stateid *stp,
1227 1227
1228static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp) 1228static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
1229{ 1229{
1230 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); 1230 lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
1231
1232 lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);
1233 1231
1234 list_del_init(&stp->st_locks); 1232 list_del_init(&stp->st_locks);
1235 nfs4_unhash_stid(&stp->st_stid); 1233 nfs4_unhash_stid(&stp->st_stid);
@@ -1238,12 +1236,12 @@ static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
1238 1236
1239static void release_lock_stateid(struct nfs4_ol_stateid *stp) 1237static void release_lock_stateid(struct nfs4_ol_stateid *stp)
1240{ 1238{
1241 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); 1239 struct nfs4_client *clp = stp->st_stid.sc_client;
1242 bool unhashed; 1240 bool unhashed;
1243 1241
1244 spin_lock(&oo->oo_owner.so_client->cl_lock); 1242 spin_lock(&clp->cl_lock);
1245 unhashed = unhash_lock_stateid(stp); 1243 unhashed = unhash_lock_stateid(stp);
1246 spin_unlock(&oo->oo_owner.so_client->cl_lock); 1244 spin_unlock(&clp->cl_lock);
1247 if (unhashed) 1245 if (unhashed)
1248 nfs4_put_stid(&stp->st_stid); 1246 nfs4_put_stid(&stp->st_stid);
1249} 1247}
@@ -4665,7 +4663,7 @@ nfs4_laundromat(struct nfsd_net *nn)
4665 * indefinitely once the lock does become free. 4663 * indefinitely once the lock does become free.
4666 */ 4664 */
4667 BUG_ON(!list_empty(&reaplist)); 4665 BUG_ON(!list_empty(&reaplist));
4668 spin_lock(&nn->client_lock); 4666 spin_lock(&nn->blocked_locks_lock);
4669 while (!list_empty(&nn->blocked_locks_lru)) { 4667 while (!list_empty(&nn->blocked_locks_lru)) {
4670 nbl = list_first_entry(&nn->blocked_locks_lru, 4668 nbl = list_first_entry(&nn->blocked_locks_lru,
4671 struct nfsd4_blocked_lock, nbl_lru); 4669 struct nfsd4_blocked_lock, nbl_lru);
@@ -4678,7 +4676,7 @@ nfs4_laundromat(struct nfsd_net *nn)
4678 list_move(&nbl->nbl_lru, &reaplist); 4676 list_move(&nbl->nbl_lru, &reaplist);
4679 list_del_init(&nbl->nbl_list); 4677 list_del_init(&nbl->nbl_list);
4680 } 4678 }
4681 spin_unlock(&nn->client_lock); 4679 spin_unlock(&nn->blocked_locks_lock);
4682 4680
4683 while (!list_empty(&reaplist)) { 4681 while (!list_empty(&reaplist)) {
4684 nbl = list_first_entry(&nn->blocked_locks_lru, 4682 nbl = list_first_entry(&nn->blocked_locks_lru,
@@ -5439,13 +5437,13 @@ nfsd4_lm_notify(struct file_lock *fl)
5439 bool queue = false; 5437 bool queue = false;
5440 5438
5441 /* An empty list means that something else is going to be using it */ 5439 /* An empty list means that something else is going to be using it */
5442 spin_lock(&nn->client_lock); 5440 spin_lock(&nn->blocked_locks_lock);
5443 if (!list_empty(&nbl->nbl_list)) { 5441 if (!list_empty(&nbl->nbl_list)) {
5444 list_del_init(&nbl->nbl_list); 5442 list_del_init(&nbl->nbl_list);
5445 list_del_init(&nbl->nbl_lru); 5443 list_del_init(&nbl->nbl_lru);
5446 queue = true; 5444 queue = true;
5447 } 5445 }
5448 spin_unlock(&nn->client_lock); 5446 spin_unlock(&nn->blocked_locks_lock);
5449 5447
5450 if (queue) 5448 if (queue)
5451 nfsd4_run_cb(&nbl->nbl_cb); 5449 nfsd4_run_cb(&nbl->nbl_cb);
@@ -5868,10 +5866,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5868 5866
5869 if (fl_flags & FL_SLEEP) { 5867 if (fl_flags & FL_SLEEP) {
5870 nbl->nbl_time = jiffies; 5868 nbl->nbl_time = jiffies;
5871 spin_lock(&nn->client_lock); 5869 spin_lock(&nn->blocked_locks_lock);
5872 list_add_tail(&nbl->nbl_list, &lock_sop->lo_blocked); 5870 list_add_tail(&nbl->nbl_list, &lock_sop->lo_blocked);
5873 list_add_tail(&nbl->nbl_lru, &nn->blocked_locks_lru); 5871 list_add_tail(&nbl->nbl_lru, &nn->blocked_locks_lru);
5874 spin_unlock(&nn->client_lock); 5872 spin_unlock(&nn->blocked_locks_lock);
5875 } 5873 }
5876 5874
5877 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock); 5875 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
@@ -5900,10 +5898,10 @@ out:
5900 if (nbl) { 5898 if (nbl) {
5901 /* dequeue it if we queued it before */ 5899 /* dequeue it if we queued it before */
5902 if (fl_flags & FL_SLEEP) { 5900 if (fl_flags & FL_SLEEP) {
5903 spin_lock(&nn->client_lock); 5901 spin_lock(&nn->blocked_locks_lock);
5904 list_del_init(&nbl->nbl_list); 5902 list_del_init(&nbl->nbl_list);
5905 list_del_init(&nbl->nbl_lru); 5903 list_del_init(&nbl->nbl_lru);
5906 spin_unlock(&nn->client_lock); 5904 spin_unlock(&nn->blocked_locks_lock);
5907 } 5905 }
5908 free_blocked_lock(nbl); 5906 free_blocked_lock(nbl);
5909 } 5907 }
@@ -6943,9 +6941,11 @@ static int nfs4_state_create_net(struct net *net)
6943 INIT_LIST_HEAD(&nn->client_lru); 6941 INIT_LIST_HEAD(&nn->client_lru);
6944 INIT_LIST_HEAD(&nn->close_lru); 6942 INIT_LIST_HEAD(&nn->close_lru);
6945 INIT_LIST_HEAD(&nn->del_recall_lru); 6943 INIT_LIST_HEAD(&nn->del_recall_lru);
6946 INIT_LIST_HEAD(&nn->blocked_locks_lru);
6947 spin_lock_init(&nn->client_lock); 6944 spin_lock_init(&nn->client_lock);
6948 6945
6946 spin_lock_init(&nn->blocked_locks_lock);
6947 INIT_LIST_HEAD(&nn->blocked_locks_lru);
6948
6949 INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main); 6949 INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
6950 get_net(net); 6950 get_net(net);
6951 6951
@@ -7063,14 +7063,14 @@ nfs4_state_shutdown_net(struct net *net)
7063 } 7063 }
7064 7064
7065 BUG_ON(!list_empty(&reaplist)); 7065 BUG_ON(!list_empty(&reaplist));
7066 spin_lock(&nn->client_lock); 7066 spin_lock(&nn->blocked_locks_lock);
7067 while (!list_empty(&nn->blocked_locks_lru)) { 7067 while (!list_empty(&nn->blocked_locks_lru)) {
7068 nbl = list_first_entry(&nn->blocked_locks_lru, 7068 nbl = list_first_entry(&nn->blocked_locks_lru,
7069 struct nfsd4_blocked_lock, nbl_lru); 7069 struct nfsd4_blocked_lock, nbl_lru);
7070 list_move(&nbl->nbl_lru, &reaplist); 7070 list_move(&nbl->nbl_lru, &reaplist);
7071 list_del_init(&nbl->nbl_list); 7071 list_del_init(&nbl->nbl_list);
7072 } 7072 }
7073 spin_unlock(&nn->client_lock); 7073 spin_unlock(&nn->blocked_locks_lock);
7074 7074
7075 while (!list_empty(&reaplist)) { 7075 while (!list_empty(&reaplist)) {
7076 nbl = list_first_entry(&nn->blocked_locks_lru, 7076 nbl = list_first_entry(&nn->blocked_locks_lru,
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index d8bd97a5a7c9..3dfd769dc5b5 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1616,7 +1616,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
1616{ 1616{
1617 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1617 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1618 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1618 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1619 __be32 seq; 1619 __be32 *seq = NULL;
1620 struct kvec iov; 1620 struct kvec iov;
1621 struct xdr_buf verf_buf; 1621 struct xdr_buf verf_buf;
1622 struct xdr_netobj mic; 1622 struct xdr_netobj mic;
@@ -1631,9 +1631,12 @@ gss_validate(struct rpc_task *task, __be32 *p)
1631 goto out_bad; 1631 goto out_bad;
1632 if (flav != RPC_AUTH_GSS) 1632 if (flav != RPC_AUTH_GSS)
1633 goto out_bad; 1633 goto out_bad;
1634 seq = htonl(task->tk_rqstp->rq_seqno); 1634 seq = kmalloc(4, GFP_NOFS);
1635 iov.iov_base = &seq; 1635 if (!seq)
1636 iov.iov_len = sizeof(seq); 1636 goto out_bad;
1637 *seq = htonl(task->tk_rqstp->rq_seqno);
1638 iov.iov_base = seq;
1639 iov.iov_len = 4;
1637 xdr_buf_from_iov(&iov, &verf_buf); 1640 xdr_buf_from_iov(&iov, &verf_buf);
1638 mic.data = (u8 *)p; 1641 mic.data = (u8 *)p;
1639 mic.len = len; 1642 mic.len = len;
@@ -1653,11 +1656,13 @@ gss_validate(struct rpc_task *task, __be32 *p)
1653 gss_put_ctx(ctx); 1656 gss_put_ctx(ctx);
1654 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n", 1657 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1655 task->tk_pid, __func__); 1658 task->tk_pid, __func__);
1659 kfree(seq);
1656 return p + XDR_QUADLEN(len); 1660 return p + XDR_QUADLEN(len);
1657out_bad: 1661out_bad:
1658 gss_put_ctx(ctx); 1662 gss_put_ctx(ctx);
1659 dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__, 1663 dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
1660 PTR_ERR(ret)); 1664 PTR_ERR(ret));
1665 kfree(seq);
1661 return ret; 1666 return ret;
1662} 1667}
1663 1668
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 244245bcbbd2..90115ceefd49 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -166,8 +166,8 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
166 unsigned int usage, struct xdr_netobj *cksumout) 166 unsigned int usage, struct xdr_netobj *cksumout)
167{ 167{
168 struct scatterlist sg[1]; 168 struct scatterlist sg[1];
169 int err; 169 int err = -1;
170 u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN]; 170 u8 *checksumdata;
171 u8 rc4salt[4]; 171 u8 rc4salt[4];
172 struct crypto_ahash *md5; 172 struct crypto_ahash *md5;
173 struct crypto_ahash *hmac_md5; 173 struct crypto_ahash *hmac_md5;
@@ -187,23 +187,22 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
187 return GSS_S_FAILURE; 187 return GSS_S_FAILURE;
188 } 188 }
189 189
190 checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_NOFS);
191 if (!checksumdata)
192 return GSS_S_FAILURE;
193
190 md5 = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC); 194 md5 = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC);
191 if (IS_ERR(md5)) 195 if (IS_ERR(md5))
192 return GSS_S_FAILURE; 196 goto out_free_cksum;
193 197
194 hmac_md5 = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, 198 hmac_md5 = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0,
195 CRYPTO_ALG_ASYNC); 199 CRYPTO_ALG_ASYNC);
196 if (IS_ERR(hmac_md5)) { 200 if (IS_ERR(hmac_md5))
197 crypto_free_ahash(md5); 201 goto out_free_md5;
198 return GSS_S_FAILURE;
199 }
200 202
201 req = ahash_request_alloc(md5, GFP_KERNEL); 203 req = ahash_request_alloc(md5, GFP_KERNEL);
202 if (!req) { 204 if (!req)
203 crypto_free_ahash(hmac_md5); 205 goto out_free_hmac_md5;
204 crypto_free_ahash(md5);
205 return GSS_S_FAILURE;
206 }
207 206
208 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); 207 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
209 208
@@ -232,11 +231,8 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
232 231
233 ahash_request_free(req); 232 ahash_request_free(req);
234 req = ahash_request_alloc(hmac_md5, GFP_KERNEL); 233 req = ahash_request_alloc(hmac_md5, GFP_KERNEL);
235 if (!req) { 234 if (!req)
236 crypto_free_ahash(hmac_md5); 235 goto out_free_hmac_md5;
237 crypto_free_ahash(md5);
238 return GSS_S_FAILURE;
239 }
240 236
241 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); 237 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
242 238
@@ -258,8 +254,12 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
258 cksumout->len = kctx->gk5e->cksumlength; 254 cksumout->len = kctx->gk5e->cksumlength;
259out: 255out:
260 ahash_request_free(req); 256 ahash_request_free(req);
261 crypto_free_ahash(md5); 257out_free_hmac_md5:
262 crypto_free_ahash(hmac_md5); 258 crypto_free_ahash(hmac_md5);
259out_free_md5:
260 crypto_free_ahash(md5);
261out_free_cksum:
262 kfree(checksumdata);
263 return err ? GSS_S_FAILURE : 0; 263 return err ? GSS_S_FAILURE : 0;
264} 264}
265 265
@@ -276,8 +276,8 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
276 struct crypto_ahash *tfm; 276 struct crypto_ahash *tfm;
277 struct ahash_request *req; 277 struct ahash_request *req;
278 struct scatterlist sg[1]; 278 struct scatterlist sg[1];
279 int err; 279 int err = -1;
280 u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN]; 280 u8 *checksumdata;
281 unsigned int checksumlen; 281 unsigned int checksumlen;
282 282
283 if (kctx->gk5e->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) 283 if (kctx->gk5e->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR)
@@ -291,15 +291,17 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
291 return GSS_S_FAILURE; 291 return GSS_S_FAILURE;
292 } 292 }
293 293
294 checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_NOFS);
295 if (checksumdata == NULL)
296 return GSS_S_FAILURE;
297
294 tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); 298 tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
295 if (IS_ERR(tfm)) 299 if (IS_ERR(tfm))
296 return GSS_S_FAILURE; 300 goto out_free_cksum;
297 301
298 req = ahash_request_alloc(tfm, GFP_KERNEL); 302 req = ahash_request_alloc(tfm, GFP_KERNEL);
299 if (!req) { 303 if (!req)
300 crypto_free_ahash(tfm); 304 goto out_free_ahash;
301 return GSS_S_FAILURE;
302 }
303 305
304 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); 306 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
305 307
@@ -349,7 +351,10 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
349 cksumout->len = kctx->gk5e->cksumlength; 351 cksumout->len = kctx->gk5e->cksumlength;
350out: 352out:
351 ahash_request_free(req); 353 ahash_request_free(req);
354out_free_ahash:
352 crypto_free_ahash(tfm); 355 crypto_free_ahash(tfm);
356out_free_cksum:
357 kfree(checksumdata);
353 return err ? GSS_S_FAILURE : 0; 358 return err ? GSS_S_FAILURE : 0;
354} 359}
355 360
@@ -368,8 +373,8 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
368 struct crypto_ahash *tfm; 373 struct crypto_ahash *tfm;
369 struct ahash_request *req; 374 struct ahash_request *req;
370 struct scatterlist sg[1]; 375 struct scatterlist sg[1];
371 int err; 376 int err = -1;
372 u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN]; 377 u8 *checksumdata;
373 unsigned int checksumlen; 378 unsigned int checksumlen;
374 379
375 if (kctx->gk5e->keyed_cksum == 0) { 380 if (kctx->gk5e->keyed_cksum == 0) {
@@ -383,16 +388,18 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
383 return GSS_S_FAILURE; 388 return GSS_S_FAILURE;
384 } 389 }
385 390
391 checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_NOFS);
392 if (!checksumdata)
393 return GSS_S_FAILURE;
394
386 tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); 395 tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
387 if (IS_ERR(tfm)) 396 if (IS_ERR(tfm))
388 return GSS_S_FAILURE; 397 goto out_free_cksum;
389 checksumlen = crypto_ahash_digestsize(tfm); 398 checksumlen = crypto_ahash_digestsize(tfm);
390 399
391 req = ahash_request_alloc(tfm, GFP_KERNEL); 400 req = ahash_request_alloc(tfm, GFP_KERNEL);
392 if (!req) { 401 if (!req)
393 crypto_free_ahash(tfm); 402 goto out_free_ahash;
394 return GSS_S_FAILURE;
395 }
396 403
397 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); 404 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
398 405
@@ -433,7 +440,10 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
433 } 440 }
434out: 441out:
435 ahash_request_free(req); 442 ahash_request_free(req);
443out_free_ahash:
436 crypto_free_ahash(tfm); 444 crypto_free_ahash(tfm);
445out_free_cksum:
446 kfree(checksumdata);
437 return err ? GSS_S_FAILURE : 0; 447 return err ? GSS_S_FAILURE : 0;
438} 448}
439 449
@@ -666,14 +676,17 @@ gss_krb5_cts_crypt(struct crypto_skcipher *cipher, struct xdr_buf *buf,
666 u32 ret; 676 u32 ret;
667 struct scatterlist sg[1]; 677 struct scatterlist sg[1];
668 SKCIPHER_REQUEST_ON_STACK(req, cipher); 678 SKCIPHER_REQUEST_ON_STACK(req, cipher);
669 u8 data[GSS_KRB5_MAX_BLOCKSIZE * 2]; 679 u8 *data;
670 struct page **save_pages; 680 struct page **save_pages;
671 u32 len = buf->len - offset; 681 u32 len = buf->len - offset;
672 682
673 if (len > ARRAY_SIZE(data)) { 683 if (len > GSS_KRB5_MAX_BLOCKSIZE * 2) {
674 WARN_ON(0); 684 WARN_ON(0);
675 return -ENOMEM; 685 return -ENOMEM;
676 } 686 }
687 data = kmalloc(GSS_KRB5_MAX_BLOCKSIZE * 2, GFP_NOFS);
688 if (!data)
689 return -ENOMEM;
677 690
678 /* 691 /*
679 * For encryption, we want to read from the cleartext 692 * For encryption, we want to read from the cleartext
@@ -708,6 +721,7 @@ gss_krb5_cts_crypt(struct crypto_skcipher *cipher, struct xdr_buf *buf,
708 ret = write_bytes_to_xdr_buf(buf, offset, data, len); 721 ret = write_bytes_to_xdr_buf(buf, offset, data, len);
709 722
710out: 723out:
724 kfree(data);
711 return ret; 725 return ret;
712} 726}
713 727
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index d67f7e1bc82d..45662d7f0943 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -718,30 +718,37 @@ gss_write_null_verf(struct svc_rqst *rqstp)
718static int 718static int
719gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq) 719gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
720{ 720{
721 __be32 xdr_seq; 721 __be32 *xdr_seq;
722 u32 maj_stat; 722 u32 maj_stat;
723 struct xdr_buf verf_data; 723 struct xdr_buf verf_data;
724 struct xdr_netobj mic; 724 struct xdr_netobj mic;
725 __be32 *p; 725 __be32 *p;
726 struct kvec iov; 726 struct kvec iov;
727 int err = -1;
727 728
728 svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS); 729 svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
729 xdr_seq = htonl(seq); 730 xdr_seq = kmalloc(4, GFP_KERNEL);
731 if (!xdr_seq)
732 return -1;
733 *xdr_seq = htonl(seq);
730 734
731 iov.iov_base = &xdr_seq; 735 iov.iov_base = xdr_seq;
732 iov.iov_len = sizeof(xdr_seq); 736 iov.iov_len = 4;
733 xdr_buf_from_iov(&iov, &verf_data); 737 xdr_buf_from_iov(&iov, &verf_data);
734 p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len; 738 p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
735 mic.data = (u8 *)(p + 1); 739 mic.data = (u8 *)(p + 1);
736 maj_stat = gss_get_mic(ctx_id, &verf_data, &mic); 740 maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
737 if (maj_stat != GSS_S_COMPLETE) 741 if (maj_stat != GSS_S_COMPLETE)
738 return -1; 742 goto out;
739 *p++ = htonl(mic.len); 743 *p++ = htonl(mic.len);
740 memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len); 744 memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len);
741 p += XDR_QUADLEN(mic.len); 745 p += XDR_QUADLEN(mic.len);
742 if (!xdr_ressize_check(rqstp, p)) 746 if (!xdr_ressize_check(rqstp, p))
743 return -1; 747 goto out;
744 return 0; 748 err = 0;
749out:
750 kfree(xdr_seq);
751 return err;
745} 752}
746 753
747struct gss_domain { 754struct gss_domain {
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
index 2d8545c34095..20027f8de129 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
@@ -177,18 +177,26 @@ xprt_rdma_bc_allocate(struct rpc_task *task)
177 return -EINVAL; 177 return -EINVAL;
178 } 178 }
179 179
180 /* svc_rdma_sendto releases this page */
180 page = alloc_page(RPCRDMA_DEF_GFP); 181 page = alloc_page(RPCRDMA_DEF_GFP);
181 if (!page) 182 if (!page)
182 return -ENOMEM; 183 return -ENOMEM;
183
184 rqst->rq_buffer = page_address(page); 184 rqst->rq_buffer = page_address(page);
185
186 rqst->rq_rbuffer = kmalloc(rqst->rq_rcvsize, RPCRDMA_DEF_GFP);
187 if (!rqst->rq_rbuffer) {
188 put_page(page);
189 return -ENOMEM;
190 }
185 return 0; 191 return 0;
186} 192}
187 193
188static void 194static void
189xprt_rdma_bc_free(struct rpc_task *task) 195xprt_rdma_bc_free(struct rpc_task *task)
190{ 196{
191 /* No-op: ctxt and page have already been freed. */ 197 struct rpc_rqst *rqst = task->tk_rqstp;
198
199 kfree(rqst->rq_rbuffer);
192} 200}
193 201
194static int 202static int
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 0137af1c0916..e01c825bc683 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2563,6 +2563,7 @@ static int bc_malloc(struct rpc_task *task)
2563 buf->len = PAGE_SIZE; 2563 buf->len = PAGE_SIZE;
2564 2564
2565 rqst->rq_buffer = buf->data; 2565 rqst->rq_buffer = buf->data;
2566 rqst->rq_rbuffer = (char *)rqst->rq_buffer + rqst->rq_callsize;
2566 return 0; 2567 return 0;
2567} 2568}
2568 2569