From b95b5089e67d0938a39feadffeae6861fb773d64 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 14 Feb 2016 14:18:31 -0800 Subject: [PATCH] 4.4-stable patches added patches: crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch crypto-atmel-sha-fix-atmel_sha_remove.patch crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch crypto-user-lock-crypto_alg_list-on-alg-dump.patch evm-use-crypto_memneq-for-digest-comparisons.patch rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch zram-don-t-call-idr_remove-from-zram_remove.patch zram-try-vmalloc-after-kmalloc.patch zram-zcomp-use-gfp_noio-to-allocate-streams.patch zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch --- ...it-for-crypto_ahash_init-to-complete.patch | 40 +++++ ...-do-not-assume-that-req-is-unchanged.patch | 150 +++++++++++++++++ ...-dereference-ctx-without-socket-lock.patch | 70 ++++++++ ...ot-set-may_backlog-on-the-async-path.patch | 41 +++++ ...rypto-atmel-sha-fix-atmel_sha_remove.patch | 37 +++++ ...-of-clk_prepare-from-atomic-contexts.patch | 99 +++++++++++ ...esa-fix-test-in-mv_cesa_dev_dma_init.patch | 31 ++++ ...ser-lock-crypto_alg_list-on-alg-dump.patch | 99 +++++++++++ ...crypto_memneq-for-digest-comparisons.patch | 44 +++++ ...e-when-eeprom-is-incorrectly-encoded.patch | 55 +++++++ ...x-errors-in-parameter-initialization.patch | 52 ++++++ queue-4.4/series | 15 ++ ...n-t-call-idr_remove-from-zram_remove.patch | 54 ++++++ .../zram-try-vmalloc-after-kmalloc.patch | 155 ++++++++++++++++++ ...omp-use-gfp_noio-to-allocate-streams.patch | 150 +++++++++++++++++ ...igrate_zspage-zs_free-race-condition.patch | 96 +++++++++++ 16 files changed, 1188 insertions(+) create mode 100644 queue-4.4/crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch create mode 100644 queue-4.4/crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch create mode 100644 queue-4.4/crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch create mode 100644 queue-4.4/crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch create mode 100644 queue-4.4/crypto-atmel-sha-fix-atmel_sha_remove.patch create mode 100644 queue-4.4/crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch create mode 100644 queue-4.4/crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch create mode 100644 queue-4.4/crypto-user-lock-crypto_alg_list-on-alg-dump.patch create mode 100644 queue-4.4/evm-use-crypto_memneq-for-digest-comparisons.patch create mode 100644 queue-4.4/rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch create mode 100644 queue-4.4/rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch create mode 100644 queue-4.4/zram-don-t-call-idr_remove-from-zram_remove.patch create mode 100644 queue-4.4/zram-try-vmalloc-after-kmalloc.patch create mode 100644 queue-4.4/zram-zcomp-use-gfp_noio-to-allocate-streams.patch create mode 100644 queue-4.4/zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch diff --git a/queue-4.4/crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch b/queue-4.4/crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch new file mode 100644 index 00000000000..932ed71ccd4 --- /dev/null +++ b/queue-4.4/crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch @@ -0,0 +1,40 @@ +From fe09786178f9df713a4b2dd6b93c0a722346bf5e Mon Sep 17 00:00:00 2001 +From: "Wang, Rui Y" +Date: Wed, 27 Jan 2016 17:08:37 +0800 +Subject: crypto: algif_hash - wait for crypto_ahash_init() to complete + +From: Wang, Rui Y + +commit fe09786178f9df713a4b2dd6b93c0a722346bf5e upstream. + +hash_sendmsg/sendpage() need to wait for the completion +of crypto_ahash_init() otherwise it can cause panic. + +Signed-off-by: Rui Wang +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algif_hash.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -54,7 +54,8 @@ static int hash_sendmsg(struct socket *s + + lock_sock(sk); + if (!ctx->more) { +- err = crypto_ahash_init(&ctx->req); ++ err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req), ++ &ctx->completion); + if (err) + goto unlock; + } +@@ -125,6 +126,7 @@ static ssize_t hash_sendpage(struct sock + } else { + if (!ctx->more) { + err = crypto_ahash_init(&ctx->req); ++ err = af_alg_wait_for_completion(err, &ctx->completion); + if (err) + goto unlock; + } diff --git a/queue-4.4/crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch b/queue-4.4/crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch new file mode 100644 index 00000000000..12f9aefeeb4 --- /dev/null +++ b/queue-4.4/crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch @@ -0,0 +1,150 @@ +From ec69bbfb9902c32a5c1492f2b1b8ad032a66d724 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 3 Feb 2016 21:39:24 +0800 +Subject: crypto: algif_skcipher - Do not assume that req is unchanged + +From: Herbert Xu + +commit ec69bbfb9902c32a5c1492f2b1b8ad032a66d724 upstream. + +The async path in algif_skcipher assumes that the crypto completion +function will be called with the original request. This is not +necessarily the case. In fact there is no need for this anyway +since we already embed information into the request with struct +skcipher_async_req. + +This patch adds a pointer to that struct and then passes it as +the data to the callback function. + +Signed-off-by: Herbert Xu +Tested-by: Tadeusz Struk +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algif_skcipher.c | 60 ++++++++++++++++++++++-------------------------- + 1 file changed, 28 insertions(+), 32 deletions(-) + +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -65,18 +65,10 @@ struct skcipher_async_req { + struct skcipher_async_rsgl first_sgl; + struct list_head list; + struct scatterlist *tsg; +- char iv[]; ++ atomic_t *inflight; ++ struct skcipher_request req; + }; + +-#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \ +- crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))) +- +-#define GET_REQ_SIZE(ctx) \ +- crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)) +- +-#define GET_IV_SIZE(ctx) \ +- crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req)) +- + #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \ + sizeof(struct scatterlist) - 1) + +@@ -102,15 +94,12 @@ static void skcipher_free_async_sgls(str + + static void skcipher_async_cb(struct crypto_async_request *req, int err) + { +- struct sock *sk = req->data; +- struct alg_sock *ask = alg_sk(sk); +- struct skcipher_ctx *ctx = ask->private; +- struct skcipher_async_req *sreq = GET_SREQ(req, ctx); ++ struct skcipher_async_req *sreq = req->data; + struct kiocb *iocb = sreq->iocb; + +- atomic_dec(&ctx->inflight); ++ atomic_dec(sreq->inflight); + skcipher_free_async_sgls(sreq); +- kfree(req); ++ kzfree(sreq); + iocb->ki_complete(iocb, err, err); + } + +@@ -509,37 +498,42 @@ static int skcipher_recvmsg_async(struct + { + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); ++ struct sock *psk = ask->parent; ++ struct alg_sock *pask = alg_sk(psk); + struct skcipher_ctx *ctx = ask->private; ++ struct skcipher_tfm *skc = pask->private; ++ struct crypto_skcipher *tfm = skc->skcipher; + struct skcipher_sg_list *sgl; + struct scatterlist *sg; + struct skcipher_async_req *sreq; + struct skcipher_request *req; + struct skcipher_async_rsgl *last_rsgl = NULL; + unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx); +- unsigned int reqlen = sizeof(struct skcipher_async_req) + +- GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx); ++ unsigned int reqsize = crypto_skcipher_reqsize(tfm); ++ unsigned int ivsize = crypto_skcipher_ivsize(tfm); + int err = -ENOMEM; + bool mark = false; ++ char *iv; + +- lock_sock(sk); +- req = kmalloc(reqlen, GFP_KERNEL); +- if (unlikely(!req)) +- goto unlock; ++ sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL); ++ if (unlikely(!sreq)) ++ goto out; + +- sreq = GET_SREQ(req, ctx); ++ req = &sreq->req; ++ iv = (char *)(req + 1) + reqsize; + sreq->iocb = msg->msg_iocb; +- memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl)); + INIT_LIST_HEAD(&sreq->list); ++ sreq->inflight = &ctx->inflight; ++ ++ lock_sock(sk); + sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); +- if (unlikely(!sreq->tsg)) { +- kfree(req); ++ if (unlikely(!sreq->tsg)) + goto unlock; +- } + sg_init_table(sreq->tsg, tx_nents); +- memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx)); +- skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req)); ++ memcpy(iv, ctx->iv, ivsize); ++ skcipher_request_set_tfm(req, tfm); + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, +- skcipher_async_cb, sk); ++ skcipher_async_cb, sreq); + + while (iov_iter_count(&msg->msg_iter)) { + struct skcipher_async_rsgl *rsgl; +@@ -615,20 +609,22 @@ static int skcipher_recvmsg_async(struct + sg_mark_end(sreq->tsg + txbufs - 1); + + skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg, +- len, sreq->iv); ++ len, iv); + err = ctx->enc ? crypto_skcipher_encrypt(req) : + crypto_skcipher_decrypt(req); + if (err == -EINPROGRESS) { + atomic_inc(&ctx->inflight); + err = -EIOCBQUEUED; ++ sreq = NULL; + goto unlock; + } + free: + skcipher_free_async_sgls(sreq); +- kfree(req); + unlock: + skcipher_wmem_wakeup(sk); + release_sock(sk); ++ kzfree(sreq); ++out: + return err; + } + diff --git a/queue-4.4/crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch b/queue-4.4/crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch new file mode 100644 index 00000000000..c069e326c96 --- /dev/null +++ b/queue-4.4/crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch @@ -0,0 +1,70 @@ +From 6454c2b83f719057069777132b13949e4c6b6350 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 3 Feb 2016 21:39:26 +0800 +Subject: crypto: algif_skcipher - Do not dereference ctx without socket lock + +From: Herbert Xu + +commit 6454c2b83f719057069777132b13949e4c6b6350 upstream. + +Any access to non-constant bits of the private context must be +done under the socket lock, in particular, this includes ctx->req. + +This patch moves such accesses under the lock, and fetches the +tfm from the parent socket which is guaranteed to be constant, +rather than from ctx->req. + +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algif_skcipher.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -295,8 +295,11 @@ static int skcipher_sendmsg(struct socke + { + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); ++ struct sock *psk = ask->parent; ++ struct alg_sock *pask = alg_sk(psk); + struct skcipher_ctx *ctx = ask->private; +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req); ++ struct skcipher_tfm *skc = pask->private; ++ struct crypto_skcipher *tfm = skc->skcipher; + unsigned ivsize = crypto_skcipher_ivsize(tfm); + struct skcipher_sg_list *sgl; + struct af_alg_control con = {}; +@@ -508,7 +511,7 @@ static int skcipher_recvmsg_async(struct + struct skcipher_async_req *sreq; + struct skcipher_request *req; + struct skcipher_async_rsgl *last_rsgl = NULL; +- unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx); ++ unsigned int txbufs = 0, len = 0, tx_nents; + unsigned int reqsize = crypto_skcipher_reqsize(tfm); + unsigned int ivsize = crypto_skcipher_ivsize(tfm); + int err = -ENOMEM; +@@ -526,6 +529,7 @@ static int skcipher_recvmsg_async(struct + sreq->inflight = &ctx->inflight; + + lock_sock(sk); ++ tx_nents = skcipher_all_sg_nents(ctx); + sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); + if (unlikely(!sreq->tsg)) + goto unlock; +@@ -633,9 +637,12 @@ static int skcipher_recvmsg_sync(struct + { + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); ++ struct sock *psk = ask->parent; ++ struct alg_sock *pask = alg_sk(psk); + struct skcipher_ctx *ctx = ask->private; +- unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm( +- &ctx->req)); ++ struct skcipher_tfm *skc = pask->private; ++ struct crypto_skcipher *tfm = skc->skcipher; ++ unsigned bs = crypto_skcipher_blocksize(tfm); + struct skcipher_sg_list *sgl; + struct scatterlist *sg; + int err = -EAGAIN; diff --git a/queue-4.4/crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch b/queue-4.4/crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch new file mode 100644 index 00000000000..604ad0a7f98 --- /dev/null +++ b/queue-4.4/crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch @@ -0,0 +1,41 @@ +From dad41997063723eaf5f77bc2015606a5a9bce320 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 3 Feb 2016 21:39:27 +0800 +Subject: crypto: algif_skcipher - Do not set MAY_BACKLOG on the async path + +From: Herbert Xu + +commit dad41997063723eaf5f77bc2015606a5a9bce320 upstream. + +The async path cannot use MAY_BACKLOG because it is not meant to +block, which is what MAY_BACKLOG does. On the other hand, both +the sync and async paths can make use of MAY_SLEEP. + +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algif_skcipher.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -536,7 +536,7 @@ static int skcipher_recvmsg_async(struct + sg_init_table(sreq->tsg, tx_nents); + memcpy(iv, ctx->iv, ivsize); + skcipher_request_set_tfm(req, tfm); +- skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, ++ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, + skcipher_async_cb, sreq); + + while (iov_iter_count(&msg->msg_iter)) { +@@ -950,7 +950,8 @@ static int skcipher_accept_parent_nokey( + ask->private = ctx; + + skcipher_request_set_tfm(&ctx->req, skcipher); +- skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, ++ skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP | ++ CRYPTO_TFM_REQ_MAY_BACKLOG, + af_alg_complete, &ctx->completion); + + sk->sk_destruct = skcipher_sock_destruct; diff --git a/queue-4.4/crypto-atmel-sha-fix-atmel_sha_remove.patch b/queue-4.4/crypto-atmel-sha-fix-atmel_sha_remove.patch new file mode 100644 index 00000000000..39bb9b2674e --- /dev/null +++ b/queue-4.4/crypto-atmel-sha-fix-atmel_sha_remove.patch @@ -0,0 +1,37 @@ +From d961436c11482e974b702c8324426208f00cd7c4 Mon Sep 17 00:00:00 2001 +From: Cyrille Pitchen +Date: Fri, 5 Feb 2016 13:45:12 +0100 +Subject: crypto: atmel-sha - fix atmel_sha_remove() + +From: Cyrille Pitchen + +commit d961436c11482e974b702c8324426208f00cd7c4 upstream. + +Since atmel_sha_probe() uses devm_xxx functions to allocate resources, +atmel_sha_remove() should no longer explicitly release them. + +Signed-off-by: Cyrille Pitchen +Fixes: b0e8b3417a62 ("crypto: atmel - use devm_xxx() managed function") +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/atmel-sha.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/crypto/atmel-sha.c ++++ b/drivers/crypto/atmel-sha.c +@@ -1484,13 +1484,6 @@ static int atmel_sha_remove(struct platf + if (sha_dd->caps.has_dma) + atmel_sha_dma_cleanup(sha_dd); + +- iounmap(sha_dd->io_base); +- +- clk_put(sha_dd->iclk); +- +- if (sha_dd->irq >= 0) +- free_irq(sha_dd->irq, sha_dd); +- + return 0; + } + diff --git a/queue-4.4/crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch b/queue-4.4/crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch new file mode 100644 index 00000000000..c6e76e7edbc --- /dev/null +++ b/queue-4.4/crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch @@ -0,0 +1,99 @@ +From c033042aa8f69894df37dabcaa0231594834a4e4 Mon Sep 17 00:00:00 2001 +From: Cyrille Pitchen +Date: Fri, 5 Feb 2016 13:45:13 +0100 +Subject: crypto: atmel-sha - remove calls of clk_prepare() from atomic contexts + +From: Cyrille Pitchen + +commit c033042aa8f69894df37dabcaa0231594834a4e4 upstream. + +clk_prepare()/clk_unprepare() must not be called within atomic context. + +This patch calls clk_prepare() once for all from atmel_sha_probe() and +clk_unprepare() from atmel_sha_remove(). + +Then calls of clk_prepare_enable()/clk_disable_unprepare() were replaced +by calls of clk_enable()/clk_disable(). + +Signed-off-by: Cyrille Pitchen +Reported-by: Matthias Mayr +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/atmel-sha.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/atmel-sha.c ++++ b/drivers/crypto/atmel-sha.c +@@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct + dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU | + SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY); + +- clk_disable_unprepare(dd->iclk); ++ clk_disable(dd->iclk); + + if (req->base.complete) + req->base.complete(&req->base, err); +@@ -796,7 +796,7 @@ static int atmel_sha_hw_init(struct atme + { + int err; + +- err = clk_prepare_enable(dd->iclk); ++ err = clk_enable(dd->iclk); + if (err) + return err; + +@@ -823,7 +823,7 @@ static void atmel_sha_hw_version_init(st + dev_info(dd->dev, + "version: 0x%x\n", dd->hw_version); + +- clk_disable_unprepare(dd->iclk); ++ clk_disable(dd->iclk); + } + + static int atmel_sha_handle_queue(struct atmel_sha_dev *dd, +@@ -1411,6 +1411,10 @@ static int atmel_sha_probe(struct platfo + goto res_err; + } + ++ err = clk_prepare(sha_dd->iclk); ++ if (err) ++ goto res_err; ++ + atmel_sha_hw_version_init(sha_dd); + + atmel_sha_get_cap(sha_dd); +@@ -1422,12 +1426,12 @@ static int atmel_sha_probe(struct platfo + if (IS_ERR(pdata)) { + dev_err(&pdev->dev, "platform data not available\n"); + err = PTR_ERR(pdata); +- goto res_err; ++ goto iclk_unprepare; + } + } + if (!pdata->dma_slave) { + err = -ENXIO; +- goto res_err; ++ goto iclk_unprepare; + } + err = atmel_sha_dma_init(sha_dd, pdata); + if (err) +@@ -1458,6 +1462,8 @@ err_algs: + if (sha_dd->caps.has_dma) + atmel_sha_dma_cleanup(sha_dd); + err_sha_dma: ++iclk_unprepare: ++ clk_unprepare(sha_dd->iclk); + res_err: + tasklet_kill(&sha_dd->done_task); + sha_dd_err: +@@ -1484,6 +1490,8 @@ static int atmel_sha_remove(struct platf + if (sha_dd->caps.has_dma) + atmel_sha_dma_cleanup(sha_dd); + ++ clk_unprepare(sha_dd->iclk); ++ + return 0; + } + diff --git a/queue-4.4/crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch b/queue-4.4/crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch new file mode 100644 index 00000000000..89cf609406a --- /dev/null +++ b/queue-4.4/crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch @@ -0,0 +1,31 @@ +From 8a3978ad55fb4c0564d285fb2f6cdee2313fce01 Mon Sep 17 00:00:00 2001 +From: Boris BREZILLON +Date: Fri, 5 Feb 2016 17:45:48 +0100 +Subject: crypto: marvell/cesa - fix test in mv_cesa_dev_dma_init() + +From: Boris BREZILLON + +commit 8a3978ad55fb4c0564d285fb2f6cdee2313fce01 upstream. + +We are checking twice if dma->cache_pool is not NULL but are never testing +dma->padding_pool value. + +Signed-off-by: Boris Brezillon +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/marvell/cesa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/marvell/cesa.c ++++ b/drivers/crypto/marvell/cesa.c +@@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct m + return -ENOMEM; + + dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0); +- if (!dma->cache_pool) ++ if (!dma->padding_pool) + return -ENOMEM; + + cesa->dma = dma; diff --git a/queue-4.4/crypto-user-lock-crypto_alg_list-on-alg-dump.patch b/queue-4.4/crypto-user-lock-crypto_alg_list-on-alg-dump.patch new file mode 100644 index 00000000000..bc0059d87a0 --- /dev/null +++ b/queue-4.4/crypto-user-lock-crypto_alg_list-on-alg-dump.patch @@ -0,0 +1,99 @@ +From 63e41ebc6630f39422d87f8a4bade1e793f37a01 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Mon, 1 Feb 2016 14:27:30 +0100 +Subject: crypto: user - lock crypto_alg_list on alg dump + +From: Mathias Krause + +commit 63e41ebc6630f39422d87f8a4bade1e793f37a01 upstream. + +We miss to take the crypto_alg_sem semaphore when traversing the +crypto_alg_list for CRYPTO_MSG_GETALG dumps. This allows a race with +crypto_unregister_alg() removing algorithms from the list while we're +still traversing it, thereby leading to a use-after-free as show below: + +[ 3482.071639] general protection fault: 0000 [#1] SMP +[ 3482.075639] Modules linked in: aes_x86_64 glue_helper lrw ablk_helper cryptd gf128mul ipv6 pcspkr serio_raw virtio_net microcode virtio_pci virtio_ring virtio sr_mod cdrom [last unloaded: aesni_intel] +[ 3482.075639] CPU: 1 PID: 11065 Comm: crconf Not tainted 4.3.4-grsec+ #126 +[ 3482.075639] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 +[ 3482.075639] task: ffff88001cd41a40 ti: ffff88001cd422c8 task.ti: ffff88001cd422c8 +[ 3482.075639] RIP: 0010:[] [] strncpy+0x13/0x30 +[ 3482.075639] RSP: 0018:ffff88001f713b60 EFLAGS: 00010202 +[ 3482.075639] RAX: ffff88001f6c4430 RBX: ffff88001f6c43a0 RCX: ffff88001f6c4430 +[ 3482.075639] RDX: 0000000000000040 RSI: fefefefefefeff16 RDI: ffff88001f6c4430 +[ 3482.075639] RBP: ffff88001f713b60 R08: ffff88001f6c4470 R09: ffff88001f6c4480 +[ 3482.075639] R10: 0000000000000002 R11: 0000000000000246 R12: ffff88001ce2aa28 +[ 3482.075639] R13: ffff880000093700 R14: ffff88001f5e4bf8 R15: 0000000000003b20 +[ 3482.075639] FS: 0000033826fa2700(0000) GS:ffff88001e900000(0000) knlGS:0000000000000000 +[ 3482.075639] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 3482.075639] CR2: ffffffffff600400 CR3: 00000000139ec000 CR4: 00000000001606f0 +[ 3482.075639] Stack: +[ 3482.075639] ffff88001f713bd8 ffffffff936ccd00 ffff88001e5c4200 ffff880000093700 +[ 3482.075639] ffff88001f713bd0 ffffffff938ef4bf 0000000000000000 0000000000003b20 +[ 3482.075639] ffff88001f5e4bf8 ffff88001f5e4848 0000000000000000 0000000000003b20 +[ 3482.075639] Call Trace: +[ 3482.075639] [] crypto_report_alg+0xc0/0x3e0 +[ 3482.075639] [] ? __alloc_skb+0x16f/0x300 +[ 3482.075639] [] crypto_dump_report+0x6a/0x90 +[ 3482.075639] [] netlink_dump+0x147/0x2e0 +[ 3482.075639] [] __netlink_dump_start+0x159/0x190 +[ 3482.075639] [] crypto_user_rcv_msg+0xc3/0x130 +[ 3482.075639] [] ? crypto_report_alg+0x3e0/0x3e0 +[ 3482.075639] [] ? alg_test_crc32c+0x120/0x120 +[ 3482.075639] [] ? __netlink_lookup+0xd5/0x120 +[ 3482.075639] [] ? crypto_add_alg+0x1d0/0x1d0 +[ 3482.075639] [] netlink_rcv_skb+0xe1/0x130 +[ 3482.075639] [] crypto_netlink_rcv+0x28/0x40 +[ 3482.075639] [] netlink_unicast+0x108/0x180 +[ 3482.075639] [] netlink_sendmsg+0x541/0x770 +[ 3482.075639] [] sock_sendmsg+0x21/0x40 +[ 3482.075639] [] SyS_sendto+0xf3/0x130 +[ 3482.075639] [] ? bad_area_nosemaphore+0x13/0x20 +[ 3482.075639] [] ? __do_page_fault+0x80/0x3a0 +[ 3482.075639] [] entry_SYSCALL_64_fastpath+0x12/0x6e +[ 3482.075639] Code: 88 4a ff 75 ed 5d 48 0f ba 2c 24 3f c3 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 85 d2 48 89 f8 48 89 f9 4c 8d 04 17 48 89 e5 74 15 <0f> b6 16 80 fa 01 88 11 48 83 de ff 48 83 c1 01 4c 39 c1 75 eb +[ 3482.075639] RIP [] strncpy+0x13/0x30 + +To trigger the race run the following loops simultaneously for a while: + $ while : ; do modprobe aesni-intel; rmmod aesni-intel; done + $ while : ; do crconf show all > /dev/null; done + +Fix the race by taking the crypto_alg_sem read lock, thereby preventing +crypto_unregister_alg() from modifying the algorithm list during the +dump. + +This bug has been detected by the PaX memory sanitize feature. + +Signed-off-by: Mathias Krause +Cc: Steffen Klassert +Cc: PaX Team +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/crypto_user.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/crypto/crypto_user.c ++++ b/crypto/crypto_user.c +@@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk + if (link->dump == NULL) + return -EINVAL; + ++ down_read(&crypto_alg_sem); + list_for_each_entry(alg, &crypto_alg_list, cra_list) + dump_alloc += CRYPTO_REPORT_MAXSIZE; + +@@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk + .done = link->done, + .min_dump_alloc = dump_alloc, + }; +- return netlink_dump_start(crypto_nlsk, skb, nlh, &c); ++ err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); + } ++ up_read(&crypto_alg_sem); ++ ++ return err; + } + + err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, diff --git a/queue-4.4/evm-use-crypto_memneq-for-digest-comparisons.patch b/queue-4.4/evm-use-crypto_memneq-for-digest-comparisons.patch new file mode 100644 index 00000000000..0c36da32485 --- /dev/null +++ b/queue-4.4/evm-use-crypto_memneq-for-digest-comparisons.patch @@ -0,0 +1,44 @@ +From 613317bd212c585c20796c10afe5daaa95d4b0a1 Mon Sep 17 00:00:00 2001 +From: Ryan Ware +Date: Thu, 11 Feb 2016 15:58:44 -0800 +Subject: EVM: Use crypto_memneq() for digest comparisons + +From: Ryan Ware + +commit 613317bd212c585c20796c10afe5daaa95d4b0a1 upstream. + +This patch fixes vulnerability CVE-2016-2085. The problem exists +because the vm_verify_hmac() function includes a use of memcmp(). +Unfortunately, this allows timing side channel attacks; specifically +a MAC forgery complexity drop from 2^128 to 2^12. This patch changes +the memcmp() to the cryptographically safe crypto_memneq(). + +Reported-by: Xiaofei Rex Guo +Signed-off-by: Ryan Ware +Signed-off-by: Mimi Zohar +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/evm/evm_main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include "evm.h" + + int evm_initialized; +@@ -148,7 +149,7 @@ static enum integrity_status evm_verify_ + xattr_value_len, calc.digest); + if (rc) + break; +- rc = memcmp(xattr_data->digest, calc.digest, ++ rc = crypto_memneq(xattr_data->digest, calc.digest, + sizeof(calc.digest)); + if (rc) + rc = -EINVAL; diff --git a/queue-4.4/rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch b/queue-4.4/rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch new file mode 100644 index 00000000000..c61003bf405 --- /dev/null +++ b/queue-4.4/rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch @@ -0,0 +1,55 @@ +From c72fc9093718a3f8597249863a1bac345ba00859 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Wed, 20 Jan 2016 21:58:39 -0600 +Subject: rtlwifi: rtl8821ae: Fix 5G failure when EEPROM is incorrectly encoded + +From: Larry Finger + +commit c72fc9093718a3f8597249863a1bac345ba00859 upstream. + +Recently, it has been reported that D-Link DWA-582 cards, which use an +RTL8812AE chip are not able to scan for 5G networks. The problems started +with kernel 4.2, which is the first version that had commit d10101a60372 +("rtlwifi: rtl8821ae: Fix problem with regulatory information"). With this +patch, the driver went from setting a default channel plan to using +the value derived from EEPROM. + +Bug reports at https://bugzilla.kernel.org/show_bug.cgi?id=111031 and +https://bugzilla.redhat.com/show_bug.cgi?id=1279653 are examples of this +problem. + +The problem was solved once I learned that the internal country code was +resulting in a regulatory set with only 2.4 GHz channels. With the RTL8821AE +chips available to me, the country code was such that both 2.4 and 5 GHz +channels are allowed. The fix is to allow both bands even when the EEPROM +is incorrectly encoded. + +Fixes: d10101a60372 ("rtlwifi: rtl8821ae: Fix problem with regulatory information") +Signed-off-by: Larry Finger +Cc: littlesmartguy@gmail.com +Cc: gabe@codehaus.org +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/realtek/rtlwifi/regd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/regd.c ++++ b/drivers/net/wireless/realtek/rtlwifi/regd.c +@@ -351,7 +351,6 @@ static const struct ieee80211_regdomain + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: +- case COUNTRY_CODE_WORLD_WIDE_13: + return &rtl_regdom_12_13; + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: +@@ -360,6 +359,7 @@ static const struct ieee80211_regdomain + return &rtl_regdom_14_60_64; + case COUNTRY_CODE_GLOBAL_DOMAIN: + return &rtl_regdom_14; ++ case COUNTRY_CODE_WORLD_WIDE_13: + case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: + return &rtl_regdom_12_13_5g_all; + default: diff --git a/queue-4.4/rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch b/queue-4.4/rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch new file mode 100644 index 00000000000..d7b1de40dfa --- /dev/null +++ b/queue-4.4/rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch @@ -0,0 +1,52 @@ +From 78bae1de422a7f6f2b4b61f6a5c379e3d7f96f44 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 14 Dec 2015 16:34:33 -0600 +Subject: rtlwifi: rtl8821ae: Fix errors in parameter initialization + +From: Larry Finger + +commit 78bae1de422a7f6f2b4b61f6a5c379e3d7f96f44 upstream. + +This driver failed to copy parameters sw_crypto and disable_watchdog into +the locations actually used by the driver. In addition, msi_support was +initialized three times and one of them used the wrong variable. The +initialization of parameter int_clear was moved so that it is near that +of the rest of the parameters. + +Signed-off-by: Larry Finger +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +@@ -95,8 +95,6 @@ int rtl8821ae_init_sw_vars(struct ieee80 + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + rtl8821ae_bt_reg_init(hw); +- rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; +- rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear; + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + + rtlpriv->dm.dm_initialgain_enable = 1; +@@ -168,12 +166,15 @@ int rtl8821ae_init_sw_vars(struct ieee80 + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; +- rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear; ++ rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear; ++ rtlpriv->cfg->mod_params->sw_crypto = ++ rtlpriv->cfg->mod_params->sw_crypto; ++ rtlpriv->cfg->mod_params->disable_watchdog = ++ rtlpriv->cfg->mod_params->disable_watchdog; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; +- rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 diff --git a/queue-4.4/series b/queue-4.4/series index 6df059ba0df..b474adcc05e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -100,3 +100,18 @@ crypto-algif_skcipher-sendmsg-sg-marking-is-off-by-one.patch crypto-caam-make-write-transactions-bufferable-on-ppc-platforms.patch crypto-chacha20-ssse3-align-stack-pointer-to-64-bytes.patch crypto-shash-fix-has_key-setting.patch +crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch +evm-use-crypto_memneq-for-digest-comparisons.patch +crypto-user-lock-crypto_alg_list-on-alg-dump.patch +crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch +crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch +crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch +crypto-atmel-sha-fix-atmel_sha_remove.patch +crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch +crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch +rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch +rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch +zram-zcomp-use-gfp_noio-to-allocate-streams.patch +zram-try-vmalloc-after-kmalloc.patch +zram-don-t-call-idr_remove-from-zram_remove.patch +zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch diff --git a/queue-4.4/zram-don-t-call-idr_remove-from-zram_remove.patch b/queue-4.4/zram-don-t-call-idr_remove-from-zram_remove.patch new file mode 100644 index 00000000000..c594cdffaa7 --- /dev/null +++ b/queue-4.4/zram-don-t-call-idr_remove-from-zram_remove.patch @@ -0,0 +1,54 @@ +From 17ec4cd985780a7e30aa45bb8f272237c12502a4 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Fri, 15 Jan 2016 16:54:48 -0800 +Subject: zram: don't call idr_remove() from zram_remove() + +From: Jerome Marchand + +commit 17ec4cd985780a7e30aa45bb8f272237c12502a4 upstream. + +The use of idr_remove() is forbidden in the callback functions of +idr_for_each(). It is therefore unsafe to call idr_remove in +zram_remove(). + +This patch moves the call to idr_remove() from zram_remove() to +hot_remove_store(). In the detroy_devices() path, idrs are removed by +idr_destroy(). This solves an use-after-free detected by KASan. + +[akpm@linux-foundation.org: fix coding stype, per Sergey] +Signed-off-by: Jerome Marchand +Acked-by: Sergey Senozhatsky +Cc: Minchan Kim +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/zram/zram_drv.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1325,7 +1325,6 @@ static int zram_remove(struct zram *zram + + pr_info("Removed device: %s\n", zram->disk->disk_name); + +- idr_remove(&zram_index_idr, zram->disk->first_minor); + blk_cleanup_queue(zram->disk->queue); + del_gendisk(zram->disk); + put_disk(zram->disk); +@@ -1367,10 +1366,12 @@ static ssize_t hot_remove_store(struct c + mutex_lock(&zram_index_mutex); + + zram = idr_find(&zram_index_idr, dev_id); +- if (zram) ++ if (zram) { + ret = zram_remove(zram); +- else ++ idr_remove(&zram_index_idr, dev_id); ++ } else { + ret = -ENODEV; ++ } + + mutex_unlock(&zram_index_mutex); + return ret ? ret : count; diff --git a/queue-4.4/zram-try-vmalloc-after-kmalloc.patch b/queue-4.4/zram-try-vmalloc-after-kmalloc.patch new file mode 100644 index 00000000000..bcfb8c67835 --- /dev/null +++ b/queue-4.4/zram-try-vmalloc-after-kmalloc.patch @@ -0,0 +1,155 @@ +From d913897abace843bba20249f3190167f7895e9c3 Mon Sep 17 00:00:00 2001 +From: Kyeongdon Kim +Date: Thu, 14 Jan 2016 15:22:29 -0800 +Subject: zram: try vmalloc() after kmalloc() + +From: Kyeongdon Kim + +commit d913897abace843bba20249f3190167f7895e9c3 upstream. + +When we're using LZ4 multi compression streams for zram swap, we found +out page allocation failure message in system running test. That was +not only once, but a few(2 - 5 times per test). Also, some failure +cases were continually occurring to try allocation order 3. + +In order to make parallel compression private data, we should call +kzalloc() with order 2/3 in runtime(lzo/lz4). But if there is no order +2/3 size memory to allocate in that time, page allocation fails. This +patch makes to use vmalloc() as fallback of kmalloc(), this prevents +page alloc failure warning. + +After using this, we never found warning message in running test, also +It could reduce process startup latency about 60-120ms in each case. + +For reference a call trace : + + Binder_1: page allocation failure: order:3, mode:0x10c0d0 + CPU: 0 PID: 424 Comm: Binder_1 Tainted: GW 3.10.49-perf-g991d02b-dirty #20 + Call trace: + dump_backtrace+0x0/0x270 + show_stack+0x10/0x1c + dump_stack+0x1c/0x28 + warn_alloc_failed+0xfc/0x11c + __alloc_pages_nodemask+0x724/0x7f0 + __get_free_pages+0x14/0x5c + kmalloc_order_trace+0x38/0xd8 + zcomp_lz4_create+0x2c/0x38 + zcomp_strm_alloc+0x34/0x78 + zcomp_strm_multi_find+0x124/0x1ec + zcomp_strm_find+0xc/0x18 + zram_bvec_rw+0x2fc/0x780 + zram_make_request+0x25c/0x2d4 + generic_make_request+0x80/0xbc + submit_bio+0xa4/0x15c + __swap_writepage+0x218/0x230 + swap_writepage+0x3c/0x4c + shrink_page_list+0x51c/0x8d0 + shrink_inactive_list+0x3f8/0x60c + shrink_lruvec+0x33c/0x4cc + shrink_zone+0x3c/0x100 + try_to_free_pages+0x2b8/0x54c + __alloc_pages_nodemask+0x514/0x7f0 + __get_free_pages+0x14/0x5c + proc_info_read+0x50/0xe4 + vfs_read+0xa0/0x12c + SyS_read+0x44/0x74 + DMA: 3397*4kB (MC) 26*8kB (RC) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB + 0*512kB 0*1024kB 0*2048kB 0*4096kB = 13796kB + +[minchan@kernel.org: change vmalloc gfp and adding comment about gfp] +[sergey.senozhatsky@gmail.com: tweak comments and styles] +Signed-off-by: Kyeongdon Kim +Signed-off-by: Minchan Kim +Acked-by: Sergey Senozhatsky +Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/zram/zcomp_lz4.c | 23 +++++++++++++++++++++-- + drivers/block/zram/zcomp_lzo.c | 23 +++++++++++++++++++++-- + 2 files changed, 42 insertions(+), 4 deletions(-) + +--- a/drivers/block/zram/zcomp_lz4.c ++++ b/drivers/block/zram/zcomp_lz4.c +@@ -10,17 +10,36 @@ + #include + #include + #include ++#include ++#include + + #include "zcomp_lz4.h" + + static void *zcomp_lz4_create(void) + { +- return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO); ++ void *ret; ++ ++ /* ++ * This function can be called in swapout/fs write path ++ * so we can't use GFP_FS|IO. And it assumes we already ++ * have at least one stream in zram initialization so we ++ * don't do best effort to allocate more stream in here. ++ * A default stream will work well without further multiple ++ * streams. That's why we use NORETRY | NOWARN. ++ */ ++ ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | ++ __GFP_NOWARN); ++ if (!ret) ++ ret = __vmalloc(LZ4_MEM_COMPRESS, ++ GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | ++ __GFP_ZERO | __GFP_HIGHMEM, ++ PAGE_KERNEL); ++ return ret; + } + + static void zcomp_lz4_destroy(void *private) + { +- kfree(private); ++ kvfree(private); + } + + static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst, +--- a/drivers/block/zram/zcomp_lzo.c ++++ b/drivers/block/zram/zcomp_lzo.c +@@ -10,17 +10,36 @@ + #include + #include + #include ++#include ++#include + + #include "zcomp_lzo.h" + + static void *lzo_create(void) + { +- return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO); ++ void *ret; ++ ++ /* ++ * This function can be called in swapout/fs write path ++ * so we can't use GFP_FS|IO. And it assumes we already ++ * have at least one stream in zram initialization so we ++ * don't do best effort to allocate more stream in here. ++ * A default stream will work well without further multiple ++ * streams. That's why we use NORETRY | NOWARN. ++ */ ++ ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY | ++ __GFP_NOWARN); ++ if (!ret) ++ ret = __vmalloc(LZO1X_MEM_COMPRESS, ++ GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN | ++ __GFP_ZERO | __GFP_HIGHMEM, ++ PAGE_KERNEL); ++ return ret; + } + + static void lzo_destroy(void *private) + { +- kfree(private); ++ kvfree(private); + } + + static int lzo_compress(const unsigned char *src, unsigned char *dst, diff --git a/queue-4.4/zram-zcomp-use-gfp_noio-to-allocate-streams.patch b/queue-4.4/zram-zcomp-use-gfp_noio-to-allocate-streams.patch new file mode 100644 index 00000000000..c9d5bddbaea --- /dev/null +++ b/queue-4.4/zram-zcomp-use-gfp_noio-to-allocate-streams.patch @@ -0,0 +1,150 @@ +From 3d5fe03a3ea013060ebba2a811aeb0f23f56aefa Mon Sep 17 00:00:00 2001 +From: Sergey Senozhatsky +Date: Thu, 14 Jan 2016 15:22:26 -0800 +Subject: zram/zcomp: use GFP_NOIO to allocate streams + +From: Sergey Senozhatsky + +commit 3d5fe03a3ea013060ebba2a811aeb0f23f56aefa upstream. + +We can end up allocating a new compression stream with GFP_KERNEL from +within the IO path, which may result is nested (recursive) IO +operations. That can introduce problems if the IO path in question is a +reclaimer, holding some locks that will deadlock nested IOs. + +Allocate streams and working memory using GFP_NOIO flag, forbidding +recursive IO and FS operations. + +An example: + + inconsistent {IN-RECLAIM_FS-W} -> {RECLAIM_FS-ON-W} usage. + git/20158 [HC0[0]:SC0[0]:HE1:SE1] takes: + (jbd2_handle){+.+.?.}, at: start_this_handle+0x4ca/0x555 + {IN-RECLAIM_FS-W} state was registered at: + __lock_acquire+0x8da/0x117b + lock_acquire+0x10c/0x1a7 + start_this_handle+0x52d/0x555 + jbd2__journal_start+0xb4/0x237 + __ext4_journal_start_sb+0x108/0x17e + ext4_dirty_inode+0x32/0x61 + __mark_inode_dirty+0x16b/0x60c + iput+0x11e/0x274 + __dentry_kill+0x148/0x1b8 + shrink_dentry_list+0x274/0x44a + prune_dcache_sb+0x4a/0x55 + super_cache_scan+0xfc/0x176 + shrink_slab.part.14.constprop.25+0x2a2/0x4d3 + shrink_zone+0x74/0x140 + kswapd+0x6b7/0x930 + kthread+0x107/0x10f + ret_from_fork+0x3f/0x70 + irq event stamp: 138297 + hardirqs last enabled at (138297): debug_check_no_locks_freed+0x113/0x12f + hardirqs last disabled at (138296): debug_check_no_locks_freed+0x33/0x12f + softirqs last enabled at (137818): __do_softirq+0x2d3/0x3e9 + softirqs last disabled at (137813): irq_exit+0x41/0x95 + + other info that might help us debug this: + Possible unsafe locking scenario: + CPU0 + ---- + lock(jbd2_handle); + + lock(jbd2_handle); + + *** DEADLOCK *** + 5 locks held by git/20158: + #0: (sb_writers#7){.+.+.+}, at: [] mnt_want_write+0x24/0x4b + #1: (&type->i_mutex_dir_key#2/1){+.+.+.}, at: [] lock_rename+0xd9/0xe3 + #2: (&sb->s_type->i_mutex_key#11){+.+.+.}, at: [] lock_two_nondirectories+0x3f/0x6b + #3: (&sb->s_type->i_mutex_key#11/4){+.+.+.}, at: [] lock_two_nondirectories+0x66/0x6b + #4: (jbd2_handle){+.+.?.}, at: [] start_this_handle+0x4ca/0x555 + + stack backtrace: + CPU: 2 PID: 20158 Comm: git Not tainted 4.1.0-rc7-next-20150615-dbg-00016-g8bdf555-dirty #211 + Call Trace: + dump_stack+0x4c/0x6e + mark_lock+0x384/0x56d + mark_held_locks+0x5f/0x76 + lockdep_trace_alloc+0xb2/0xb5 + kmem_cache_alloc_trace+0x32/0x1e2 + zcomp_strm_alloc+0x25/0x73 [zram] + zcomp_strm_multi_find+0xe7/0x173 [zram] + zcomp_strm_find+0xc/0xe [zram] + zram_bvec_rw+0x2ca/0x7e0 [zram] + zram_make_request+0x1fa/0x301 [zram] + generic_make_request+0x9c/0xdb + submit_bio+0xf7/0x120 + ext4_io_submit+0x2e/0x43 + ext4_bio_write_page+0x1b7/0x300 + mpage_submit_page+0x60/0x77 + mpage_map_and_submit_buffers+0x10f/0x21d + ext4_writepages+0xc8c/0xe1b + do_writepages+0x23/0x2c + __filemap_fdatawrite_range+0x84/0x8b + filemap_flush+0x1c/0x1e + ext4_alloc_da_blocks+0xb8/0x117 + ext4_rename+0x132/0x6dc + ? mark_held_locks+0x5f/0x76 + ext4_rename2+0x29/0x2b + vfs_rename+0x540/0x636 + SyS_renameat2+0x359/0x44d + SyS_rename+0x1e/0x20 + entry_SYSCALL_64_fastpath+0x12/0x6f + +[minchan@kernel.org: add stable mark] +Signed-off-by: Sergey Senozhatsky +Acked-by: Minchan Kim +Cc: Kyeongdon Kim +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/zram/zcomp.c | 4 ++-- + drivers/block/zram/zcomp_lz4.c | 2 +- + drivers/block/zram/zcomp_lzo.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/block/zram/zcomp.c ++++ b/drivers/block/zram/zcomp.c +@@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp + */ + static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) + { +- struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); ++ struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO); + if (!zstrm) + return NULL; + +@@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_all + * allocate 2 pages. 1 for compressed data, plus 1 extra for the + * case when compressed size is larger than the original one + */ +- zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); ++ zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1); + if (!zstrm->private || !zstrm->buffer) { + zcomp_strm_free(comp, zstrm); + zstrm = NULL; +--- a/drivers/block/zram/zcomp_lz4.c ++++ b/drivers/block/zram/zcomp_lz4.c +@@ -15,7 +15,7 @@ + + static void *zcomp_lz4_create(void) + { +- return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL); ++ return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO); + } + + static void zcomp_lz4_destroy(void *private) +--- a/drivers/block/zram/zcomp_lzo.c ++++ b/drivers/block/zram/zcomp_lzo.c +@@ -15,7 +15,7 @@ + + static void *lzo_create(void) + { +- return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); ++ return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO); + } + + static void lzo_destroy(void *private) diff --git a/queue-4.4/zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch b/queue-4.4/zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch new file mode 100644 index 00000000000..f18ddd2a2c4 --- /dev/null +++ b/queue-4.4/zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch @@ -0,0 +1,96 @@ +From c102f07ca0b04f2cb49cfc161c83f6239d17f491 Mon Sep 17 00:00:00 2001 +From: Junil Lee +Date: Wed, 20 Jan 2016 14:58:18 -0800 +Subject: zsmalloc: fix migrate_zspage-zs_free race condition + +From: Junil Lee + +commit c102f07ca0b04f2cb49cfc161c83f6239d17f491 upstream. + +record_obj() in migrate_zspage() does not preserve handle's +HANDLE_PIN_BIT, set by find_aloced_obj()->trypin_tag(), and implicitly +(accidentally) un-pins the handle, while migrate_zspage() still performs +an explicit unpin_tag() on the that handle. This additional explicit +unpin_tag() introduces a race condition with zs_free(), which can pin +that handle by this time, so the handle becomes un-pinned. + +Schematically, it goes like this: + + CPU0 CPU1 + migrate_zspage + find_alloced_obj + trypin_tag + set HANDLE_PIN_BIT zs_free() + pin_tag() + obj_malloc() -- new object, no tag + record_obj() -- remove HANDLE_PIN_BIT set HANDLE_PIN_BIT + unpin_tag() -- remove zs_free's HANDLE_PIN_BIT + +The race condition may result in a NULL pointer dereference: + + Unable to handle kernel NULL pointer dereference at virtual address 00000000 + CPU: 0 PID: 19001 Comm: CookieMonsterCl Tainted: + PC is at get_zspage_mapping+0x0/0x24 + LR is at obj_free.isra.22+0x64/0x128 + Call trace: + get_zspage_mapping+0x0/0x24 + zs_free+0x88/0x114 + zram_free_page+0x64/0xcc + zram_slot_free_notify+0x90/0x108 + swap_entry_free+0x278/0x294 + free_swap_and_cache+0x38/0x11c + unmap_single_vma+0x480/0x5c8 + unmap_vmas+0x44/0x60 + exit_mmap+0x50/0x110 + mmput+0x58/0xe0 + do_exit+0x320/0x8dc + do_group_exit+0x44/0xa8 + get_signal+0x538/0x580 + do_signal+0x98/0x4b8 + do_notify_resume+0x14/0x5c + +This patch keeps the lock bit in migration path and update value +atomically. + +Signed-off-by: Junil Lee +Signed-off-by: Minchan Kim +Acked-by: Vlastimil Babka +Cc: Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/zsmalloc.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -309,7 +309,12 @@ static void free_handle(struct zs_pool * + + static void record_obj(unsigned long handle, unsigned long obj) + { +- *(unsigned long *)handle = obj; ++ /* ++ * lsb of @obj represents handle lock while other bits ++ * represent object value the handle is pointing so ++ * updating shouldn't do store tearing. ++ */ ++ WRITE_ONCE(*(unsigned long *)handle, obj); + } + + /* zpool driver */ +@@ -1635,6 +1640,13 @@ static int migrate_zspage(struct zs_pool + free_obj = obj_malloc(d_page, class, handle); + zs_object_copy(free_obj, used_obj, class); + index++; ++ /* ++ * record_obj updates handle's value to free_obj and it will ++ * invalidate lock bit(ie, HANDLE_PIN_BIT) of handle, which ++ * breaks synchronization using pin_tag(e,g, zs_free) so ++ * let's keep the lock bit. ++ */ ++ free_obj |= BIT(HANDLE_PIN_BIT); + record_obj(handle, free_obj); + unpin_tag(handle); + obj_free(pool, class, used_obj); -- 2.47.3