Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The driver fails to remove its debugfs directory on device removal or module unload, leading to a dangling debugfs entry that can cause a use-after-free and kernel panic.
--
--- Patch [1]: [PATCH 5.15] crypto: sun4i-ss - Remove insecure and unused rng_alg ---
commit 170a30200701519fc546c370a0ab6113fdc3a608
Author: Eric Biggers <ebiggers@kernel.org>
crypto: sun4i-ss - Remove insecure and unused rng_alg
This commit removes the sun4i_ss_rng implementation because it is insecure,
has multiple vulnerabilities including a buffer overflow, and is unused.
There is no point in fixing these issues individually when the code is
unneeded.
Closes: https://lore.kernel.org/r/af749a8447bd7f0e9dd26ca6c87e9c6afecb09d9@linux.dev/
> diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
> --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
> +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
[ ... ]
> @@ -535,9 +502,6 @@ static int sun4i_ss_remove(struct platform_device *pdev)
> case CRYPTO_ALG_TYPE_AHASH:
> crypto_unregister_ahash(&ss_algs[i].alg.hash);
> break;
> - case CRYPTO_ALG_TYPE_RNG:
> - crypto_unregister_rng(&ss_algs[i].alg.rng);
> - break;
> }
> }
>
[Severity: High]
This is a pre-existing issue, but does this function leak the debugfs
directory when the module is removed?
In sun4i_ss_probe(), the driver sets up the debugfs entries:
ss->dbgfs_dir = debugfs_create_dir("sun4i-ss", NULL);
ss->dbgfs_stats = debugfs_create_file("stats", 0444, ss->dbgfs_dir, ss,
&sun4i_ss_debugfs_fops);
Since sun4i_ss_remove() lacks a corresponding debugfs_remove_recursive()
call, could unloading the module leave the debugfs entries registered in the
VFS, leading to a use-after-free and kernel panic if someone opens
/sys/kernel/debug/sun4i-ss/stats after the module memory is freed?
@@ -168,7 +168,6 @@ CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRYPTO_DEV_SUN4I_SS=y
-CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_CE=y
CONFIG_CRYPTO_DEV_SUN8I_SS=y
CONFIG_DMA_CMA=y
@@ -24,14 +24,6 @@ config CRYPTO_DEV_SUN4I_SS
To compile this driver as a module, choose M here: the module
will be called sun4i-ss.
-config CRYPTO_DEV_SUN4I_SS_PRNG
- bool "Support for Allwinner Security System PRNG"
- depends on CRYPTO_DEV_SUN4I_SS
- select CRYPTO_RNG
- help
- Select this option if you want to provide kernel-side support for
- the Pseudo-Random Number Generator found in the Security System.
-
config CRYPTO_DEV_SUN4I_SS_DEBUG
bool "Enable sun4i-ss stats"
depends on CRYPTO_DEV_SUN4I_SS
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sun4i-ss.o
sun4i-ss-y += sun4i-ss-core.o sun4i-ss-hash.o sun4i-ss-cipher.o
-sun4i-ss-$(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG) += sun4i-ss-prng.o
@@ -216,23 +216,6 @@ static struct sun4i_ss_alg_template ss_algs[] = {
}
}
},
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
-{
- .type = CRYPTO_ALG_TYPE_RNG,
- .alg.rng = {
- .base = {
- .cra_name = "stdrng",
- .cra_driver_name = "sun4i_ss_rng",
- .cra_priority = 300,
- .cra_ctxsize = 0,
- .cra_module = THIS_MODULE,
- },
- .generate = sun4i_ss_prng_generate,
- .seed = sun4i_ss_prng_seed,
- .seedsize = SS_SEED_LEN / BITS_PER_BYTE,
- }
-},
-#endif
};
static int sun4i_ss_dbgfs_read(struct seq_file *seq, void *v)
@@ -250,12 +233,6 @@ static int sun4i_ss_dbgfs_read(struct seq_file *seq, void *v)
ss_algs[i].stat_req, ss_algs[i].stat_opti, ss_algs[i].stat_fb,
ss_algs[i].stat_bytes);
break;
- case CRYPTO_ALG_TYPE_RNG:
- seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n",
- ss_algs[i].alg.rng.base.cra_driver_name,
- ss_algs[i].alg.rng.base.cra_name,
- ss_algs[i].stat_req, ss_algs[i].stat_bytes);
- break;
case CRYPTO_ALG_TYPE_AHASH:
seq_printf(seq, "%s %s reqs=%lu\n",
ss_algs[i].alg.hash.halg.base.cra_driver_name,
@@ -486,13 +463,6 @@ static int sun4i_ss_probe(struct platform_device *pdev)
goto error_alg;
}
break;
- case CRYPTO_ALG_TYPE_RNG:
- err = crypto_register_rng(&ss_algs[i].alg.rng);
- if (err) {
- dev_err(ss->dev, "Fail to register %s\n",
- ss_algs[i].alg.rng.base.cra_name);
- }
- break;
}
}
@@ -512,9 +482,6 @@ static int sun4i_ss_probe(struct platform_device *pdev)
case CRYPTO_ALG_TYPE_AHASH:
crypto_unregister_ahash(&ss_algs[i].alg.hash);
break;
- case CRYPTO_ALG_TYPE_RNG:
- crypto_unregister_rng(&ss_algs[i].alg.rng);
- break;
}
}
error_pm:
@@ -535,9 +502,6 @@ static int sun4i_ss_remove(struct platform_device *pdev)
case CRYPTO_ALG_TYPE_AHASH:
crypto_unregister_ahash(&ss_algs[i].alg.hash);
break;
- case CRYPTO_ALG_TYPE_RNG:
- crypto_unregister_rng(&ss_algs[i].alg.rng);
- break;
}
}
deleted file mode 100644
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-#include "sun4i-ss.h"
-
-int sun4i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen)
-{
- struct sun4i_ss_alg_template *algt;
- struct rng_alg *alg = crypto_rng_alg(tfm);
-
- algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
- memcpy(algt->ss->seed, seed, slen);
-
- return 0;
-}
-
-int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen)
-{
- struct sun4i_ss_alg_template *algt;
- struct rng_alg *alg = crypto_rng_alg(tfm);
- int i, err;
- u32 v;
- u32 *data = (u32 *)dst;
- const u32 mode = SS_OP_PRNG | SS_PRNG_CONTINUE | SS_ENABLED;
- size_t len;
- struct sun4i_ss_ctx *ss;
- unsigned int todo = (dlen / 4) * 4;
-
- algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
- ss = algt->ss;
-
- err = pm_runtime_resume_and_get(ss->dev);
- if (err < 0)
- return err;
-
- if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
- algt->stat_req++;
- algt->stat_bytes += todo;
- }
-
- spin_lock_bh(&ss->slock);
-
- writel(mode, ss->base + SS_CTL);
-
- while (todo > 0) {
- /* write the seed */
- for (i = 0; i < SS_SEED_LEN / BITS_PER_LONG; i++)
- writel(ss->seed[i], ss->base + SS_KEY0 + i * 4);
-
- /* Read the random data */
- len = min_t(size_t, SS_DATA_LEN / BITS_PER_BYTE, todo);
- readsl(ss->base + SS_TXFIFO, data, len / 4);
- data += len / 4;
- todo -= len;
-
- /* Update the seed */
- for (i = 0; i < SS_SEED_LEN / BITS_PER_LONG; i++) {
- v = readl(ss->base + SS_KEY0 + i * 4);
- ss->seed[i] = v;
- }
- }
-
- writel(0, ss->base + SS_CTL);
- spin_unlock_bh(&ss->slock);
-
- pm_runtime_put(ss->dev);
-
- return 0;
-}
@@ -31,8 +31,6 @@
#include <crypto/internal/skcipher.h>
#include <crypto/aes.h>
#include <crypto/internal/des.h>
-#include <crypto/internal/rng.h>
-#include <crypto/rng.h>
#define SS_CTL 0x00
#define SS_KEY0 0x04
@@ -62,10 +60,6 @@
/* SS_CTL configuration values */
-/* PRNG generator mode - bit 15 */
-#define SS_PRNG_ONESHOT (0 << 15)
-#define SS_PRNG_CONTINUE (1 << 15)
-
/* IV mode for hash */
#define SS_IV_ARBITRARY (1 << 14)
@@ -94,14 +88,10 @@
#define SS_OP_3DES (2 << 4)
#define SS_OP_SHA1 (3 << 4)
#define SS_OP_MD5 (4 << 4)
-#define SS_OP_PRNG (5 << 4)
/* Data end bit - bit 2 */
#define SS_DATA_END (1 << 2)
-/* PRNG start bit - bit 1 */
-#define SS_PRNG_START (1 << 1)
-
/* SS Enable bit - bit 0 */
#define SS_DISABLED (0 << 0)
#define SS_ENABLED (1 << 0)
@@ -128,9 +118,6 @@
#define SS_RXFIFO_EMP_INT_ENABLE (1 << 2)
#define SS_TXFIFO_AVA_INT_ENABLE (1 << 0)
-#define SS_SEED_LEN 192
-#define SS_DATA_LEN 160
-
/*
* struct ss_variant - Describe SS hardware variant
* @sha1_in_be: The SHA1 digest is given by SS in BE, and so need to be inverted.
@@ -151,9 +138,6 @@ struct sun4i_ss_ctx {
char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */
spinlock_t slock; /* control the use of the device */
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
- u32 seed[SS_SEED_LEN / BITS_PER_LONG];
-#endif
struct dentry *dbgfs_dir;
struct dentry *dbgfs_stats;
};
@@ -164,7 +148,6 @@ struct sun4i_ss_alg_template {
union {
struct skcipher_alg crypto;
struct ahash_alg hash;
- struct rng_alg rng;
} alg;
struct sun4i_ss_ctx *ss;
unsigned long stat_req;
@@ -230,6 +213,3 @@ int sun4i_ss_des_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen);
int sun4i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen);
-int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen);
-int sun4i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);