This patchset fixes CVE-2022-48629
Brian Masney (1): crypto: qcom-rng - ensure buffer for generate is completely filled
Ondrej Mosnacek (1): crypto: qcom-rng - fix infinite loop on requests not multiple of WORD_SZ
drivers/crypto/qcom-rng.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
From: Brian Masney bmasney@redhat.com
stable inclusion from stable-v4.19.236 commit a8e32bbb96c25b7ab29b1894dcd45e0b3b08fd9d category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I963KI CVE: CVE-2022-48629
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit a680b1832ced3b5fa7c93484248fd221ea0d614b upstream.
The generate function in struct rng_alg expects that the destination buffer is completely filled if the function returns 0. qcom_rng_read() can run into a situation where the buffer is partially filled with randomness and the remaining part of the buffer is zeroed since qcom_rng_generate() doesn't check the return value. This issue can be reproduced by running the following from libkcapi:
kcapi-rng -b 9000000 > OUTFILE
The generated OUTFILE will have three huge sections that contain all zeros, and this is caused by the code where the test 'val & PRNG_STATUS_DATA_AVAIL' fails.
Let's fix this issue by ensuring that qcom_rng_read() always returns with a full buffer if the function returns success. Let's also have qcom_rng_generate() return the correct value.
Here's some statistics from the ent project (https://www.fourmilab.ch/random/) that shows information about the quality of the generated numbers:
$ ent -c qcom-random-before Value Char Occurrences Fraction 0 606748 0.067416 1 33104 0.003678 2 33001 0.003667 ... 253 � 32883 0.003654 254 � 33035 0.003671 255 � 33239 0.003693
Total: 9000000 1.000000
Entropy = 7.811590 bits per byte.
Optimum compression would reduce the size of this 9000000 byte file by 2 percent.
Chi square distribution for 9000000 samples is 9329962.81, and randomly would exceed this value less than 0.01 percent of the times.
Arithmetic mean value of data bytes is 119.3731 (127.5 = random). Monte Carlo value for Pi is 3.197293333 (error 1.77 percent). Serial correlation coefficient is 0.159130 (totally uncorrelated = 0.0).
Without this patch, the results of the chi-square test is 0.01%, and the numbers are certainly not random according to ent's project page. The results improve with this patch:
$ ent -c qcom-random-after Value Char Occurrences Fraction 0 35432 0.003937 1 35127 0.003903 2 35424 0.003936 ... 253 � 35201 0.003911 254 � 34835 0.003871 255 � 35368 0.003930
Total: 9000000 1.000000
Entropy = 7.999979 bits per byte.
Optimum compression would reduce the size of this 9000000 byte file by 0 percent.
Chi square distribution for 9000000 samples is 258.77, and randomly would exceed this value 42.24 percent of the times.
Arithmetic mean value of data bytes is 127.5006 (127.5 = random). Monte Carlo value for Pi is 3.141277333 (error 0.01 percent). Serial correlation coefficient is 0.000468 (totally uncorrelated = 0.0).
This change was tested on a Nexus 5 phone (msm8974 SoC).
Signed-off-by: Brian Masney bmasney@redhat.com Fixes: ceec5f5b5988 ("crypto: qcom-rng - Add Qcom prng driver") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Andrew Halaney ahalaney@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: GUO Zihua guozihua@huawei.com --- drivers/crypto/qcom-rng.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c index e54249ccc009..e41ca58bf7b6 100644 --- a/drivers/crypto/qcom-rng.c +++ b/drivers/crypto/qcom-rng.c @@ -7,6 +7,7 @@ #include <linux/acpi.h> #include <linux/clk.h> #include <linux/crypto.h> +#include <linux/iopoll.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -42,16 +43,19 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max) { unsigned int currsize = 0; u32 val; + int ret;
/* read random data from hardware */ do { - val = readl_relaxed(rng->base + PRNG_STATUS); - if (!(val & PRNG_STATUS_DATA_AVAIL)) - break; + ret = readl_poll_timeout(rng->base + PRNG_STATUS, val, + val & PRNG_STATUS_DATA_AVAIL, + 200, 10000); + if (ret) + return ret;
val = readl_relaxed(rng->base + PRNG_DATA_OUT); if (!val) - break; + return -EINVAL;
if ((max - currsize) >= WORD_SZ) { memcpy(data, &val, WORD_SZ); @@ -60,11 +64,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max) } else { /* copy only remaining bytes */ memcpy(data, &val, max - currsize); - break; } } while (currsize < max);
- return currsize; + return 0; }
static int qcom_rng_generate(struct crypto_rng *tfm, @@ -86,7 +89,7 @@ static int qcom_rng_generate(struct crypto_rng *tfm, mutex_unlock(&rng->lock); clk_disable_unprepare(rng->clk);
- return 0; + return ret; }
static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
From: Ondrej Mosnacek omosnace@redhat.com
stable inclusion from stable-v4.19.245 commit 71a89789552b7faf3ef27969b9bc783fa0df3550 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I963KI CVE: CVE-2022-48629
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 16287397ec5c08aa58db6acf7dbc55470d78087d upstream.
The commit referenced in the Fixes tag removed the 'break' from the else branch in qcom_rng_read(), causing an infinite loop whenever 'max' is not a multiple of WORD_SZ. This can be reproduced e.g. by running:
kcapi-rng -b 67 >/dev/null
There are many ways to fix this without adding back the 'break', but they all seem more awkward than simply adding it back, so do just that.
Tested on a machine with Qualcomm Amberwing processor.
Fixes: a680b1832ced ("crypto: qcom-rng - ensure buffer for generate is completely filled") Cc: stable@vger.kernel.org Signed-off-by: Ondrej Mosnacek omosnace@redhat.com Reviewed-by: Brian Masney bmasney@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: GUO Zihua guozihua@huawei.com --- drivers/crypto/qcom-rng.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c index e41ca58bf7b6..818e3e9479fe 100644 --- a/drivers/crypto/qcom-rng.c +++ b/drivers/crypto/qcom-rng.c @@ -64,6 +64,7 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max) } else { /* copy only remaining bytes */ memcpy(data, &val, max - currsize); + break; } } while (currsize < max);
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/5209 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/5...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/5209 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/5...