Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfsd-4.9-1' of git://linux-nfs.org/~bfields/linux

Pull nfsd bugfixes from Bruce Fields:
"Fixes for some recent regressions including fallout from the vmalloc'd
stack change (after which we can no longer encrypt stuff on the
stack)"

* tag 'nfsd-4.9-1' of git://linux-nfs.org/~bfields/linux:
nfsd: Fix general protection fault in release_lock_stateid()
svcrdma: backchannel cannot share a page for send and rcv buffers
sunrpc: fix some missing rq_rbuffer assignments
sunrpc: don't pass on-stack memory to sg_set_buf
nfsd: move blocked lock handling under a dedicated spinlock

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