Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: null - Use spin lock instead of mutex

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@syzkaller.appspotmail.com
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+25 -12
+25 -12
crypto/crypto_null.c
··· 17 17 #include <crypto/internal/skcipher.h> 18 18 #include <linux/init.h> 19 19 #include <linux/module.h> 20 - #include <linux/mm.h> 20 + #include <linux/spinlock.h> 21 21 #include <linux/string.h> 22 22 23 - static DEFINE_MUTEX(crypto_default_null_skcipher_lock); 23 + static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock); 24 24 static struct crypto_sync_skcipher *crypto_default_null_skcipher; 25 25 static int crypto_default_null_skcipher_refcnt; 26 26 ··· 152 152 153 153 struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void) 154 154 { 155 + struct crypto_sync_skcipher *ntfm = NULL; 155 156 struct crypto_sync_skcipher *tfm; 156 157 157 - mutex_lock(&crypto_default_null_skcipher_lock); 158 + spin_lock_bh(&crypto_default_null_skcipher_lock); 158 159 tfm = crypto_default_null_skcipher; 159 160 160 161 if (!tfm) { 161 - tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0); 162 - if (IS_ERR(tfm)) 163 - goto unlock; 162 + spin_unlock_bh(&crypto_default_null_skcipher_lock); 164 163 165 - crypto_default_null_skcipher = tfm; 164 + ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0); 165 + if (IS_ERR(ntfm)) 166 + return ntfm; 167 + 168 + spin_lock_bh(&crypto_default_null_skcipher_lock); 169 + tfm = crypto_default_null_skcipher; 170 + if (!tfm) { 171 + tfm = ntfm; 172 + ntfm = NULL; 173 + crypto_default_null_skcipher = tfm; 174 + } 166 175 } 167 176 168 177 crypto_default_null_skcipher_refcnt++; 178 + spin_unlock_bh(&crypto_default_null_skcipher_lock); 169 179 170 - unlock: 171 - mutex_unlock(&crypto_default_null_skcipher_lock); 180 + crypto_free_sync_skcipher(ntfm); 172 181 173 182 return tfm; 174 183 } ··· 185 176 186 177 void crypto_put_default_null_skcipher(void) 187 178 { 188 - mutex_lock(&crypto_default_null_skcipher_lock); 179 + struct crypto_sync_skcipher *tfm = NULL; 180 + 181 + spin_lock_bh(&crypto_default_null_skcipher_lock); 189 182 if (!--crypto_default_null_skcipher_refcnt) { 190 - crypto_free_sync_skcipher(crypto_default_null_skcipher); 183 + tfm = crypto_default_null_skcipher; 191 184 crypto_default_null_skcipher = NULL; 192 185 } 193 - mutex_unlock(&crypto_default_null_skcipher_lock); 186 + spin_unlock_bh(&crypto_default_null_skcipher_lock); 187 + 188 + crypto_free_sync_skcipher(tfm); 194 189 } 195 190 EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher); 196 191