[PATCH] crypto: null - Use spin lock instead of mutex
From: Herbert Xu
Date: Wed Feb 12 2025 - 01:10:33 EST
On Mon, Dec 30, 2024 at 11:22:28AM -0800, syzbot wrote:
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: a024e377efed net: llc: reset skb->transport_header
> git tree: net
> console+strace: https://syzkaller.appspot.com/x/log.txt?x=15c7f0b0580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=6a2b862bf4a5409f
> dashboard link: https://syzkaller.appspot.com/bug?extid=b3e02953598f447d4d2a
> compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=14bce818580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=12bce818580000
>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/f2ea524d69fe/disk-a024e377.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/b39d227b097d/vmlinux-a024e377.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/8ee66636253f/bzImage-a024e377.xz
---8<---
As the null algorithm may be freed in softirq context through
af_alg, use spin locks instead of mutexes to protect the default
null algorithm.
Reported-by: syzbot+b3e02953598f447d4d2a@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index 5b84b0f7cc17..337867028653 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -17,10 +17,10 @@
#include <crypto/internal/skcipher.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/mm.h>
+#include <linux/spinlock.h>
#include <linux/string.h>
-static DEFINE_MUTEX(crypto_default_null_skcipher_lock);
+static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock);
static struct crypto_sync_skcipher *crypto_default_null_skcipher;
static int crypto_default_null_skcipher_refcnt;
@@ -152,23 +152,32 @@ MODULE_ALIAS_CRYPTO("cipher_null");
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
{
+ struct crypto_sync_skcipher *ntfm = NULL;
struct crypto_sync_skcipher *tfm;
- mutex_lock(&crypto_default_null_skcipher_lock);
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
tfm = crypto_default_null_skcipher;
if (!tfm) {
- tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
- if (IS_ERR(tfm))
- goto unlock;
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
- crypto_default_null_skcipher = tfm;
+ ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
+ if (IS_ERR(ntfm))
+ return ntfm;
+
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
+ tfm = crypto_default_null_skcipher;
+ if (!tfm) {
+ tfm = ntfm;
+ ntfm = NULL;
+ crypto_default_null_skcipher = tfm;
+ }
}
crypto_default_null_skcipher_refcnt++;
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
-unlock:
- mutex_unlock(&crypto_default_null_skcipher_lock);
+ crypto_free_sync_skcipher(ntfm);
return tfm;
}
@@ -176,12 +185,16 @@ EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
void crypto_put_default_null_skcipher(void)
{
- mutex_lock(&crypto_default_null_skcipher_lock);
+ struct crypto_sync_skcipher *tfm = NULL;
+
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
if (!--crypto_default_null_skcipher_refcnt) {
- crypto_free_sync_skcipher(crypto_default_null_skcipher);
+ tfm = crypto_default_null_skcipher;
crypto_default_null_skcipher = NULL;
}
- mutex_unlock(&crypto_default_null_skcipher_lock);
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
+
+ crypto_free_sync_skcipher(tfm);
}
EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
--
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt