From 815b3c208637abb04d81cd434f4b3661cfecf3d6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Jun 2020 22:31:43 +0200 Subject: [PATCH] 5.6-stable patches added patches: crypto-algapi-avoid-spurious-modprobe-on-loaded.patch crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch io_uring-fix-flush-req-refs-underflow.patch io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch --- ...pi-avoid-spurious-modprobe-on-loaded.patch | 44 ++++++ ...vice-when-ndevlist-is-fully-iterated.patch | 45 ++++++ ...rror-return-code-in-drbg_alloc_state.patch | 38 +++++ ...n-in-__virtio_crypto_skcipher_do_req.patch | 51 ++++++ ...n-in-__virtio_crypto_skcipher_do_req.patch | 76 +++++++++ ...-virtio_crypto_skcipher_finalize_req.patch | 71 +++++++++ ...o_uring-fix-flush-req-refs-underflow.patch | 34 ++++ ..._wait-calls-in-io_uring_cancel_files.patch | 55 +++++++ queue-5.6/series | 9 ++ ...-whole-page-is-affected-and-poisoned.patch | 145 ++++++++++++++++++ 10 files changed, 568 insertions(+) create mode 100644 queue-5.6/crypto-algapi-avoid-spurious-modprobe-on-loaded.patch create mode 100644 queue-5.6/crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch create mode 100644 queue-5.6/crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch create mode 100644 queue-5.6/crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch create mode 100644 queue-5.6/crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch create mode 100644 queue-5.6/crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch create mode 100644 queue-5.6/io_uring-fix-flush-req-refs-underflow.patch create mode 100644 queue-5.6/io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch create mode 100644 queue-5.6/x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch diff --git a/queue-5.6/crypto-algapi-avoid-spurious-modprobe-on-loaded.patch b/queue-5.6/crypto-algapi-avoid-spurious-modprobe-on-loaded.patch new file mode 100644 index 00000000000..00fadc649df --- /dev/null +++ b/queue-5.6/crypto-algapi-avoid-spurious-modprobe-on-loaded.patch @@ -0,0 +1,44 @@ +From beeb460cd12ac9b91640b484b6a52dcba9d9fc8f Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 6 Apr 2020 23:02:40 -0700 +Subject: crypto: algapi - Avoid spurious modprobe on LOADED + +From: Eric Biggers + +commit beeb460cd12ac9b91640b484b6a52dcba9d9fc8f upstream. + +Currently after any algorithm is registered and tested, there's an +unnecessary request_module("cryptomgr") even if it's already loaded. +Also, CRYPTO_MSG_ALG_LOADED is sent twice, and thus if the algorithm is +"crct10dif", lib/crc-t10dif.c replaces the tfm twice rather than once. + +This occurs because CRYPTO_MSG_ALG_LOADED is sent using +crypto_probing_notify(), which tries to load "cryptomgr" if the +notification is not handled (NOTIFY_DONE). This doesn't make sense +because "cryptomgr" doesn't handle this notification. + +Fix this by using crypto_notify() instead of crypto_probing_notify(). + +Fixes: dd8b083f9a5e ("crypto: api - Introduce notifier for new crypto algorithms") +Cc: # v4.20+ +Cc: Martin K. Petersen +Signed-off-by: Eric Biggers +Reviewed-by: Martin K. Petersen +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algapi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/algapi.c ++++ b/crypto/algapi.c +@@ -403,7 +403,7 @@ static void crypto_wait_for_test(struct + err = wait_for_completion_killable(&larval->completion); + WARN_ON(err); + if (!err) +- crypto_probing_notify(CRYPTO_MSG_ALG_LOADED, larval); ++ crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); + + out: + crypto_larval_kill(&larval->alg); diff --git a/queue-5.6/crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch b/queue-5.6/crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch new file mode 100644 index 00000000000..2eb9ce634ea --- /dev/null +++ b/queue-5.6/crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch @@ -0,0 +1,45 @@ +From 320bdbd816156f9ca07e5fed7bfb449f2908dda7 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 30 May 2020 15:35:37 +0200 +Subject: crypto: cavium/nitrox - Fix 'nitrox_get_first_device()' when ndevlist is fully iterated + +From: Christophe JAILLET + +commit 320bdbd816156f9ca07e5fed7bfb449f2908dda7 upstream. + +When a list is completely iterated with 'list_for_each_entry(x, ...)', x is +not NULL at the end. + +While at it, remove a useless initialization of the ndev variable. It +is overridden by 'list_for_each_entry'. + +Fixes: f2663872f073 ("crypto: cavium - Register the CNN55XX supported crypto algorithms.") +Cc: +Signed-off-by: Christophe JAILLET +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/cavium/nitrox/nitrox_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/cavium/nitrox/nitrox_main.c ++++ b/drivers/crypto/cavium/nitrox/nitrox_main.c +@@ -278,7 +278,7 @@ static void nitrox_remove_from_devlist(s + + struct nitrox_device *nitrox_get_first_device(void) + { +- struct nitrox_device *ndev = NULL; ++ struct nitrox_device *ndev; + + mutex_lock(&devlist_lock); + list_for_each_entry(ndev, &ndevlist, list) { +@@ -286,7 +286,7 @@ struct nitrox_device *nitrox_get_first_d + break; + } + mutex_unlock(&devlist_lock); +- if (!ndev) ++ if (&ndev->list == &ndevlist) + return NULL; + + refcount_inc(&ndev->refcnt); diff --git a/queue-5.6/crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch b/queue-5.6/crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch new file mode 100644 index 00000000000..beb81882aea --- /dev/null +++ b/queue-5.6/crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch @@ -0,0 +1,38 @@ +From e0664ebcea6ac5e16da703409fb4bd61f8cd37d9 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Thu, 30 Apr 2020 08:13:53 +0000 +Subject: crypto: drbg - fix error return code in drbg_alloc_state() + +From: Wei Yongjun + +commit e0664ebcea6ac5e16da703409fb4bd61f8cd37d9 upstream. + +Fix to return negative error code -ENOMEM from the kzalloc error handling +case instead of 0, as done elsewhere in this function. + +Reported-by: Xiumei Mu +Fixes: db07cd26ac6a ("crypto: drbg - add FIPS 140-2 CTRNG for noise source") +Cc: +Signed-off-by: Wei Yongjun +Reviewed-by: Stephan Mueller +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/drbg.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/crypto/drbg.c ++++ b/crypto/drbg.c +@@ -1294,8 +1294,10 @@ static inline int drbg_alloc_state(struc + if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) { + drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags), + GFP_KERNEL); +- if (!drbg->prev) ++ if (!drbg->prev) { ++ ret = -ENOMEM; + goto fini; ++ } + drbg->fips_primed = false; + } + diff --git a/queue-5.6/crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch b/queue-5.6/crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch new file mode 100644 index 00000000000..2fff30c4ac8 --- /dev/null +++ b/queue-5.6/crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch @@ -0,0 +1,51 @@ +From d90ca42012db2863a9a30b564a2ace6016594bda Mon Sep 17 00:00:00 2001 +From: "Longpeng(Mike)" +Date: Tue, 2 Jun 2020 15:05:01 +0800 +Subject: crypto: virtio: Fix dest length calculation in __virtio_crypto_skcipher_do_req() + +From: Longpeng(Mike) + +commit d90ca42012db2863a9a30b564a2ace6016594bda upstream. + +The src/dst length is not aligned with AES_BLOCK_SIZE(which is 16) in some +testcases in tcrypto.ko. + +For example, the src/dst length of one of cts(cbc(aes))'s testcase is 17, the +crypto_virtio driver will set @src_data_len=16 but @dst_data_len=17 in this +case and get a wrong at then end. + + SRC: pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp (17 bytes) + EXP: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc pp (17 bytes) + DST: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc 00 (pollute the last bytes) + (pp: plaintext cc:ciphertext) + +Fix this issue by limit the length of dest buffer. + +Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver") +Cc: Gonglei +Cc: Herbert Xu +Cc: "Michael S. Tsirkin" +Cc: Jason Wang +Cc: "David S. Miller" +Cc: virtualization@lists.linux-foundation.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Longpeng(Mike) +Link: https://lore.kernel.org/r/20200602070501.2023-4-longpeng2@huawei.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/virtio/virtio_crypto_algs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/crypto/virtio/virtio_crypto_algs.c ++++ b/drivers/crypto/virtio/virtio_crypto_algs.c +@@ -402,6 +402,7 @@ __virtio_crypto_skcipher_do_req(struct v + goto free; + } + ++ dst_len = min_t(unsigned int, req->cryptlen, dst_len); + pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n", + req->cryptlen, dst_len); + diff --git a/queue-5.6/crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch b/queue-5.6/crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch new file mode 100644 index 00000000000..95179230336 --- /dev/null +++ b/queue-5.6/crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch @@ -0,0 +1,76 @@ +From b02989f37fc5e865ceeee9070907e4493b3a21e2 Mon Sep 17 00:00:00 2001 +From: "Longpeng(Mike)" +Date: Tue, 2 Jun 2020 15:04:59 +0800 +Subject: crypto: virtio: Fix src/dst scatterlist calculation in __virtio_crypto_skcipher_do_req() + +From: Longpeng(Mike) + +commit b02989f37fc5e865ceeee9070907e4493b3a21e2 upstream. + +The system will crash when the users insmod crypto/tcrypt.ko with mode=38 +( testing "cts(cbc(aes))" ). + +Usually the next entry of one sg will be @sg@ + 1, but if this sg element +is part of a chained scatterlist, it could jump to the start of a new +scatterlist array. Fix it by sg_next() on calculation of src/dst +scatterlist. + +Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver") +Reported-by: LABBE Corentin +Cc: Herbert Xu +Cc: "Michael S. Tsirkin" +Cc: Jason Wang +Cc: "David S. Miller" +Cc: virtualization@lists.linux-foundation.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200123101000.GB24255@Red +Signed-off-by: Gonglei +Signed-off-by: Longpeng(Mike) +Link: https://lore.kernel.org/r/20200602070501.2023-2-longpeng2@huawei.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/virtio/virtio_crypto_algs.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/virtio/virtio_crypto_algs.c ++++ b/drivers/crypto/virtio/virtio_crypto_algs.c +@@ -350,13 +350,18 @@ __virtio_crypto_skcipher_do_req(struct v + int err; + unsigned long flags; + struct scatterlist outhdr, iv_sg, status_sg, **sgs; +- int i; + u64 dst_len; + unsigned int num_out = 0, num_in = 0; + int sg_total; + uint8_t *iv; ++ struct scatterlist *sg; + + src_nents = sg_nents_for_len(req->src, req->cryptlen); ++ if (src_nents < 0) { ++ pr_err("Invalid number of src SG.\n"); ++ return src_nents; ++ } ++ + dst_nents = sg_nents(req->dst); + + pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n", +@@ -443,12 +448,12 @@ __virtio_crypto_skcipher_do_req(struct v + vc_sym_req->iv = iv; + + /* Source data */ +- for (i = 0; i < src_nents; i++) +- sgs[num_out++] = &req->src[i]; ++ for (sg = req->src; src_nents; sg = sg_next(sg), src_nents--) ++ sgs[num_out++] = sg; + + /* Destination data */ +- for (i = 0; i < dst_nents; i++) +- sgs[num_out + num_in++] = &req->dst[i]; ++ for (sg = req->dst; sg; sg = sg_next(sg)) ++ sgs[num_out + num_in++] = sg; + + /* Status */ + sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status)); diff --git a/queue-5.6/crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch b/queue-5.6/crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch new file mode 100644 index 00000000000..ec8f16b2ac4 --- /dev/null +++ b/queue-5.6/crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch @@ -0,0 +1,71 @@ +From 8c855f0720ff006d75d0a2512c7f6c4f60ff60ee Mon Sep 17 00:00:00 2001 +From: "Longpeng(Mike)" +Date: Tue, 2 Jun 2020 15:05:00 +0800 +Subject: crypto: virtio: Fix use-after-free in virtio_crypto_skcipher_finalize_req() + +From: Longpeng(Mike) + +commit 8c855f0720ff006d75d0a2512c7f6c4f60ff60ee upstream. + +The system'll crash when the users insmod crypto/tcrypto.ko with mode=155 +( testing "authenc(hmac(sha1),cbc(aes))" ). It's caused by reuse the memory +of request structure. + +In crypto_authenc_init_tfm(), the reqsize is set to: + [PART 1] sizeof(authenc_request_ctx) + + [PART 2] ictx->reqoff + + [PART 3] MAX(ahash part, skcipher part) +and the 'PART 3' is used by both ahash and skcipher in turn. + +When the virtio_crypto driver finish skcipher req, it'll call ->complete +callback(in crypto_finalize_skcipher_request) and then free its +resources whose pointers are recorded in 'skcipher parts'. + +However, the ->complete is 'crypto_authenc_encrypt_done' in this case, +it will use the 'ahash part' of the request and change its content, +so virtio_crypto driver will get the wrong pointer after ->complete +finish and mistakenly free some other's memory. So the system will crash +when these memory will be used again. + +The resources which need to be cleaned up are not used any more. But the +pointers of these resources may be changed in the function +"crypto_finalize_skcipher_request". Thus release specific resources before +calling this function. + +Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver") +Reported-by: LABBE Corentin +Cc: Gonglei +Cc: Herbert Xu +Cc: "Michael S. Tsirkin" +Cc: Jason Wang +Cc: "David S. Miller" +Cc: virtualization@lists.linux-foundation.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200123101000.GB24255@Red +Acked-by: Gonglei +Signed-off-by: Longpeng(Mike) +Link: https://lore.kernel.org/r/20200602070501.2023-3-longpeng2@huawei.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/virtio/virtio_crypto_algs.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/virtio/virtio_crypto_algs.c ++++ b/drivers/crypto/virtio/virtio_crypto_algs.c +@@ -578,10 +578,11 @@ static void virtio_crypto_skcipher_final + scatterwalk_map_and_copy(req->iv, req->dst, + req->cryptlen - AES_BLOCK_SIZE, + AES_BLOCK_SIZE, 0); +- crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine, +- req, err); + kzfree(vc_sym_req->iv); + virtcrypto_clear_request(&vc_sym_req->base); ++ ++ crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine, ++ req, err); + } + + static struct virtio_crypto_algo virtio_crypto_algs[] = { { diff --git a/queue-5.6/io_uring-fix-flush-req-refs-underflow.patch b/queue-5.6/io_uring-fix-flush-req-refs-underflow.patch new file mode 100644 index 00000000000..7f4ef14ec00 --- /dev/null +++ b/queue-5.6/io_uring-fix-flush-req-refs-underflow.patch @@ -0,0 +1,34 @@ +From 4518a3cc273cf82efdd36522fb1f13baad173c70 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Tue, 26 May 2020 20:34:02 +0300 +Subject: io_uring: fix flush req->refs underflow + +From: Pavel Begunkov + +commit 4518a3cc273cf82efdd36522fb1f13baad173c70 upstream. + +In io_uring_cancel_files(), after refcount_sub_and_test() leaves 0 +req->refs, it calls io_put_req(), which would also put a ref. Call +io_free_req() instead. + +Cc: stable@vger.kernel.org +Fixes: 2ca10259b418 ("io_uring: prune request from overflow list on flush") +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + fs/io_uring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6529,7 +6529,7 @@ static void io_uring_cancel_files(struct + * all we had, then we're done with this request. + */ + if (refcount_sub_and_test(2, &cancel_req->refs)) { +- io_put_req(cancel_req); ++ io_free_req(cancel_req); + finish_wait(&ctx->inflight_wait, &wait); + continue; + } diff --git a/queue-5.6/io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch b/queue-5.6/io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch new file mode 100644 index 00000000000..1e68bb9e411 --- /dev/null +++ b/queue-5.6/io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch @@ -0,0 +1,55 @@ +From d8f1b9716cfd1a1f74c0fedad40c5f65a25aa208 Mon Sep 17 00:00:00 2001 +From: Xiaoguang Wang +Date: Sun, 26 Apr 2020 15:54:43 +0800 +Subject: io_uring: fix mismatched finish_wait() calls in io_uring_cancel_files() + +From: Xiaoguang Wang + +commit d8f1b9716cfd1a1f74c0fedad40c5f65a25aa208 upstream. + +The prepare_to_wait() and finish_wait() calls in io_uring_cancel_files() +are mismatched. Currently I don't see any issues related this bug, just +find it by learning codes. + +Signed-off-by: Xiaoguang Wang +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + fs/io_uring.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6488,11 +6488,9 @@ static int io_uring_release(struct inode + static void io_uring_cancel_files(struct io_ring_ctx *ctx, + struct files_struct *files) + { +- struct io_kiocb *req; +- DEFINE_WAIT(wait); +- + while (!list_empty_careful(&ctx->inflight_list)) { +- struct io_kiocb *cancel_req = NULL; ++ struct io_kiocb *cancel_req = NULL, *req; ++ DEFINE_WAIT(wait); + + spin_lock_irq(&ctx->inflight_lock); + list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { +@@ -6532,6 +6530,7 @@ static void io_uring_cancel_files(struct + */ + if (refcount_sub_and_test(2, &cancel_req->refs)) { + io_put_req(cancel_req); ++ finish_wait(&ctx->inflight_wait, &wait); + continue; + } + } +@@ -6539,8 +6538,8 @@ static void io_uring_cancel_files(struct + io_wq_cancel_work(ctx->io_wq, &cancel_req->work); + io_put_req(cancel_req); + schedule(); ++ finish_wait(&ctx->inflight_wait, &wait); + } +- finish_wait(&ctx->inflight_wait, &wait); + } + + static int io_uring_flush(struct file *file, void *data) diff --git a/queue-5.6/series b/queue-5.6/series index 06fe7379265..03d8bc3899d 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -92,3 +92,12 @@ spi-bcm-qspi-handle-clock-probe-deferral.patch spi-bcm-qspi-when-tx-rx-buffer-is-null-set-to-0.patch pm-runtime-clk-fix-clk_pm_runtime_get-error-path.patch gup-document-and-work-around-cow-can-break-either-way-issue.patch +crypto-cavium-nitrox-fix-nitrox_get_first_device-when-ndevlist-is-fully-iterated.patch +crypto-algapi-avoid-spurious-modprobe-on-loaded.patch +crypto-drbg-fix-error-return-code-in-drbg_alloc_state.patch +crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.patch +crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch +crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch +io_uring-fix-mismatched-finish_wait-calls-in-io_uring_cancel_files.patch +io_uring-fix-flush-req-refs-underflow.patch +x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch diff --git a/queue-5.6/x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch b/queue-5.6/x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch new file mode 100644 index 00000000000..358afa5dba6 --- /dev/null +++ b/queue-5.6/x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch @@ -0,0 +1,145 @@ +From 17fae1294ad9d711b2c3dd0edef479d40c76a5e8 Mon Sep 17 00:00:00 2001 +From: Tony Luck +Date: Wed, 20 May 2020 09:35:46 -0700 +Subject: x86/{mce,mm}: Unmap the entire page if the whole page is affected and poisoned + +From: Tony Luck + +commit 17fae1294ad9d711b2c3dd0edef479d40c76a5e8 upstream. + +An interesting thing happened when a guest Linux instance took a machine +check. The VMM unmapped the bad page from guest physical space and +passed the machine check to the guest. + +Linux took all the normal actions to offline the page from the process +that was using it. But then guest Linux crashed because it said there +was a second machine check inside the kernel with this stack trace: + +do_memory_failure + set_mce_nospec + set_memory_uc + _set_memory_uc + change_page_attr_set_clr + cpa_flush + clflush_cache_range_opt + +This was odd, because a CLFLUSH instruction shouldn't raise a machine +check (it isn't consuming the data). Further investigation showed that +the VMM had passed in another machine check because is appeared that the +guest was accessing the bad page. + +Fix is to check the scope of the poison by checking the MCi_MISC register. +If the entire page is affected, then unmap the page. If only part of the +page is affected, then mark the page as uncacheable. + +This assumes that VMMs will do the logical thing and pass in the "whole +page scope" via the MCi_MISC register (since they unmapped the entire +page). + + [ bp: Adjust to x86/entry changes. ] + +Fixes: 284ce4011ba6 ("x86/memory_failure: Introduce {set, clear}_mce_nospec()") +Reported-by: Jue Wang +Signed-off-by: Tony Luck +Signed-off-by: Borislav Petkov +Signed-off-by: Thomas Gleixner +Tested-by: Jue Wang +Cc: +Link: https://lkml.kernel.org/r/20200520163546.GA7977@agluck-desk2.amr.corp.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/set_memory.h | 19 +++++++++++++------ + arch/x86/kernel/cpu/mce/core.c | 11 +++++++++-- + include/linux/set_memory.h | 2 +- + 3 files changed, 23 insertions(+), 9 deletions(-) + +--- a/arch/x86/include/asm/set_memory.h ++++ b/arch/x86/include/asm/set_memory.h +@@ -83,28 +83,35 @@ int set_direct_map_default_noflush(struc + extern int kernel_set_to_readonly; + + #ifdef CONFIG_X86_64 +-static inline int set_mce_nospec(unsigned long pfn) ++/* ++ * Prevent speculative access to the page by either unmapping ++ * it (if we do not require access to any part of the page) or ++ * marking it uncacheable (if we want to try to retrieve data ++ * from non-poisoned lines in the page). ++ */ ++static inline int set_mce_nospec(unsigned long pfn, bool unmap) + { + unsigned long decoy_addr; + int rc; + + /* +- * Mark the linear address as UC to make sure we don't log more +- * errors because of speculative access to the page. + * We would like to just call: +- * set_memory_uc((unsigned long)pfn_to_kaddr(pfn), 1); ++ * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1); + * but doing that would radically increase the odds of a + * speculative access to the poison page because we'd have + * the virtual address of the kernel 1:1 mapping sitting + * around in registers. + * Instead we get tricky. We create a non-canonical address + * that looks just like the one we want, but has bit 63 flipped. +- * This relies on set_memory_uc() properly sanitizing any __pa() ++ * This relies on set_memory_XX() properly sanitizing any __pa() + * results with __PHYSICAL_MASK or PTE_PFN_MASK. + */ + decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); + +- rc = set_memory_uc(decoy_addr, 1); ++ if (unmap) ++ rc = set_memory_np(decoy_addr, 1); ++ else ++ rc = set_memory_uc(decoy_addr, 1); + if (rc) + pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); + return rc; +--- a/arch/x86/kernel/cpu/mce/core.c ++++ b/arch/x86/kernel/cpu/mce/core.c +@@ -527,6 +527,13 @@ bool mce_is_memory_error(struct mce *m) + } + EXPORT_SYMBOL_GPL(mce_is_memory_error); + ++static bool whole_page(struct mce *m) ++{ ++ if (!mca_cfg.ser || !(m->status & MCI_STATUS_MISCV)) ++ return true; ++ return MCI_MISC_ADDR_LSB(m->misc) >= PAGE_SHIFT; ++} ++ + bool mce_is_correctable(struct mce *m) + { + if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED) +@@ -598,7 +605,7 @@ static int uc_decode_notifier(struct not + + pfn = mce->addr >> PAGE_SHIFT; + if (!memory_failure(pfn, 0)) +- set_mce_nospec(pfn); ++ set_mce_nospec(pfn, whole_page(mce)); + + return NOTIFY_OK; + } +@@ -1096,7 +1103,7 @@ static int do_memory_failure(struct mce + if (ret) + pr_err("Memory error not recovered"); + else +- set_mce_nospec(m->addr >> PAGE_SHIFT); ++ set_mce_nospec(m->addr >> PAGE_SHIFT, whole_page(m)); + return ret; + } + +--- a/include/linux/set_memory.h ++++ b/include/linux/set_memory.h +@@ -26,7 +26,7 @@ static inline int set_direct_map_default + #endif + + #ifndef set_mce_nospec +-static inline int set_mce_nospec(unsigned long pfn) ++static inline int set_mce_nospec(unsigned long pfn, bool unmap) + { + return 0; + } -- 2.47.2