s390/crypto: fix possible sleep during spinlock aquired
authorHarald Freudenberger <freude@linux.ibm.com>
Mon, 27 May 2019 13:24:20 +0000 (15:24 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 5 Oct 2019 15:19:49 +0000 (16:19 +0100)
commit 1c2c7029c008922d4d48902cc386250502e73d51 upstream.

This patch fixes a complain about possible sleep during
spinlock aquired
"BUG: sleeping function called from invalid context at
include/crypto/algapi.h:426"
for the ctr(aes) and ctr(des) s390 specific ciphers.

Instead of using a spinlock this patch introduces a mutex
which is save to be held in sleeping context. Please note
a deadlock is not possible as mutex_trylock() is used.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reported-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
[bwh: Backported to 3.16:
 - Replace spin_unlock() on all exit paths
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/s390/crypto/aes_s390.c
arch/s390/crypto/des_s390.c

index 1f272b24fc0bf9393d44939ea2b225a84e36ea2a..941dd9415b6aae79fdc1ff99f0d6451661151cd0 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include "crypt_s390.h"
 
 #define AES_KEYLEN_128         1
@@ -33,7 +33,7 @@
 #define AES_KEYLEN_256         4
 
 static u8 *ctrblk;
-static DEFINE_SPINLOCK(ctrblk_lock);
+static DEFINE_MUTEX(ctrblk_lock);
 static char keylen_flag;
 
 struct s390_aes_ctx {
@@ -785,7 +785,7 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
        if (!walk->nbytes)
                return ret;
 
-       if (spin_trylock(&ctrblk_lock))
+       if (mutex_trylock(&ctrblk_lock))
                ctrptr = ctrblk;
 
        memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE);
@@ -801,7 +801,7 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
                                               n, ctrptr);
                        if (ret < 0 || ret != n) {
                                if (ctrptr == ctrblk)
-                                       spin_unlock(&ctrblk_lock);
+                                       mutex_unlock(&ctrblk_lock);
                                return -EIO;
                        }
                        if (n > AES_BLOCK_SIZE)
@@ -819,7 +819,7 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
                        memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE);
                else
                        memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
-               spin_unlock(&ctrblk_lock);
+               mutex_unlock(&ctrblk_lock);
        } else {
                if (!nbytes)
                        memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
index 9e05cc453a40d5fd946ecf56f1063f2446812695..b4733d80521ee9251d31f8183fc5e091fb0eab01 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/crypto.h>
+#include <linux/mutex.h>
 #include <crypto/algapi.h>
 #include <crypto/des.h>
 
@@ -25,7 +26,7 @@
 #define DES3_KEY_SIZE  (3 * DES_KEY_SIZE)
 
 static u8 *ctrblk;
-static DEFINE_SPINLOCK(ctrblk_lock);
+static DEFINE_MUTEX(ctrblk_lock);
 
 struct s390_des_ctx {
        u8 iv[DES_BLOCK_SIZE];
@@ -394,7 +395,7 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
        if (!walk->nbytes)
                return ret;
 
-       if (spin_trylock(&ctrblk_lock))
+       if (mutex_trylock(&ctrblk_lock))
                ctrptr = ctrblk;
 
        memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE);
@@ -410,7 +411,7 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
                                               n, ctrptr);
                        if (ret < 0 || ret != n) {
                                if (ctrptr == ctrblk)
-                                       spin_unlock(&ctrblk_lock);
+                                       mutex_unlock(&ctrblk_lock);
                                return -EIO;
                        }
                        if (n > DES_BLOCK_SIZE)
@@ -428,7 +429,7 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
                        memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE);
                else
                        memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
-               spin_unlock(&ctrblk_lock);
+               mutex_unlock(&ctrblk_lock);
        } else {
                if (!nbytes)
                        memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);