Le vendredi 13 janvier 2012 à 11:41 +0100, Eric Dumazet a écrit : > And a plain kmalloc() is enough, since we fully initialize the array a > bit later. > > for (i = 0; i < 16; i++) > LOAD_OP(i, W, input); > for (i = 16; i < 80; i++) { > BLEND_OP(i, W); > } Here is an official patch ;) [PATCH v3] crypto: sha512 - Fix msg_schedule race The percpu msg_schedule setup was unsafe as a user in a process context can be interrupted by a softirq user which would then scribble over the exact same work area. Bug reported by Alexey Dobriyan, and diagnosed by Steffen Klassert. Bug added in commit f9e2bca6c22 (crypto: sha512 - Move message schedule W[80] to static percpu area) Try a dynamic memory allocation, and fallback using a single static area, guarded by a spinlock. This removes use of percpu memory. Reported-by: Alexey Dobriyan <adobriyan@xxxxxxxxx> Signed-off-by: Eric Dumazet <eric.dumazet@xxxxxxxxx> CC: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> CC: Adrian-Ken Rueegsegger <ken@xxxxxxxxxxx> CC: Steffen Klassert <steffen.klassert@xxxxxxxxxxx> --- crypto/sha512_generic.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 9ed9f60..b52ef9b 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -18,10 +18,8 @@ #include <linux/crypto.h> #include <linux/types.h> #include <crypto/sha.h> -#include <linux/percpu.h> #include <asm/byteorder.h> -static DEFINE_PER_CPU(u64[80], msg_schedule); static inline u64 Ch(u64 x, u64 y, u64 z) { @@ -87,10 +85,15 @@ static void sha512_transform(u64 *state, const u8 *input) { u64 a, b, c, d, e, f, g, h, t1, t2; - + static u64 msg_schedule[80]; + static DEFINE_SPINLOCK(msg_schedule_lock); int i; - u64 *W = get_cpu_var(msg_schedule); + u64 *W = kmalloc(sizeof(msg_schedule), GFP_ATOMIC | __GFP_NOWARN); + if (!W) { + spin_lock_bh(&msg_schedule_lock); + W = msg_schedule; + } /* load the input */ for (i = 0; i < 16; i++) LOAD_OP(i, W, input); @@ -128,8 +131,11 @@ sha512_transform(u64 *state, const u8 *input) /* erase our data */ a = b = c = d = e = f = g = h = t1 = t2 = 0; - memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); - put_cpu_var(msg_schedule); + memset(W, 0, sizeof(msg_schedule)); + if (W == msg_schedule) + spin_unlock_bh(&msg_schedule_lock); + else + kfree(W); } static int -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html