From: Greg Kroah-Hartman Date: Thu, 9 Aug 2012 19:37:08 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.5.2~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a893d9d04c6dd6c1a71ca999ad5d57a240e5bdf;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: random-add-support-for-architectural-random-hooks.patch random-make-add_interrupt_randomness-do-something-sane.patch random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch --- diff --git a/queue-3.0/random-add-support-for-architectural-random-hooks.patch b/queue-3.0/random-add-support-for-architectural-random-hooks.patch new file mode 100644 index 00000000000..e599d051dfd --- /dev/null +++ b/queue-3.0/random-add-support-for-architectural-random-hooks.patch @@ -0,0 +1,95 @@ +From 63d77173266c1791f1553e9e8ccea65dc87c4485 Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Sun, 31 Jul 2011 13:54:50 -0700 +Subject: random: Add support for architectural random hooks + +From: "H. Peter Anvin" + +commit 63d77173266c1791f1553e9e8ccea65dc87c4485 upstream. + +Add support for architecture-specific hooks into the kernel-directed +random number generator interfaces. This patchset does not use the +architecture random number generator interfaces for the +userspace-directed interfaces (/dev/random and /dev/urandom), thus +eliminating the need to distinguish between them based on a pool +pointer. + +Changes in version 3: +- Moved the hooks from extract_entropy() to get_random_bytes(). +- Changes the hooks to inlines. + +Signed-off-by: H. Peter Anvin +Cc: Fenghua Yu +Cc: Matt Mackall +Cc: Herbert Xu +Cc: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 23 +++++++++++++++++++++-- + include/linux/random.h | 13 +++++++++++++ + 2 files changed, 34 insertions(+), 2 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -932,7 +932,21 @@ static ssize_t extract_entropy_user(stru + */ + void get_random_bytes(void *buf, int nbytes) + { +- extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); ++ char *p = buf; ++ ++ while (nbytes) { ++ unsigned long v; ++ int chunk = min(nbytes, (int)sizeof(unsigned long)); ++ ++ if (!arch_get_random_long(&v)) ++ break; ++ ++ memcpy(buf, &v, chunk); ++ p += chunk; ++ nbytes -= chunk; ++ } ++ ++ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); + } + EXPORT_SYMBOL(get_random_bytes); + +@@ -1318,9 +1332,14 @@ late_initcall(random_int_secret_init); + DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); + unsigned int get_random_int(void) + { +- __u32 *hash = get_cpu_var(get_random_int_hash); ++ __u32 *hash; + unsigned int ret; + ++ if (arch_get_random_int(&ret)) ++ return ret; ++ ++ hash = get_cpu_var(get_random_int_hash); ++ + hash[0] += current->pid + jiffies + get_cycles(); + md5_transform(hash, random_int_secret); + ret = hash[0]; +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -91,6 +91,19 @@ static inline void prandom32_seed(struct + state->s3 = __seed(i, 15); + } + ++#ifdef CONFIG_ARCH_RANDOM ++# include ++#else ++static inline int arch_get_random_long(unsigned long *v) ++{ ++ return 0; ++} ++static inline int arch_get_random_int(unsigned int *v) ++{ ++ return 0; ++} ++#endif ++ + #endif /* __KERNEL___ */ + + #endif /* _LINUX_RANDOM_H */ diff --git a/queue-3.0/random-make-add_interrupt_randomness-do-something-sane.patch b/queue-3.0/random-make-add_interrupt_randomness-do-something-sane.patch new file mode 100644 index 00000000000..8f67be5a23c --- /dev/null +++ b/queue-3.0/random-make-add_interrupt_randomness-do-something-sane.patch @@ -0,0 +1,279 @@ +From 775f4b297b780601e61787b766f306ed3e1d23eb Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 2 Jul 2012 07:52:16 -0400 +Subject: random: make 'add_interrupt_randomness()' do something sane + +From: Theodore Ts'o + +commit 775f4b297b780601e61787b766f306ed3e1d23eb upstream. + +We've been moving away from add_interrupt_randomness() for various +reasons: it's too expensive to do on every interrupt, and flooding the +CPU with interrupts could theoretically cause bogus floods of entropy +from a somewhat externally controllable source. + +This solves both problems by limiting the actual randomness addition +to just once a second or after 64 interrupts, whicever comes first. +During that time, the interrupt cycle data is buffered up in a per-cpu +pool. Also, we make sure the the nonblocking pool used by urandom is +initialized before we start feeding the normal input pool. This +assures that /dev/urandom is returning unpredictable data as soon as +possible. + +(Based on an original patch by Linus, but significantly modified by +tytso.) + +Tested-by: Eric Wustrow +Reported-by: Eric Wustrow +Reported-by: Nadia Heninger +Reported-by: Zakir Durumeric +Reported-by: J. Alex Halderman . +Signed-off-by: Linus Torvalds +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 103 ++++++++++++++++++++++++++++++++++++++-------- + drivers/mfd/ab3100-core.c | 2 + include/linux/random.h | 2 + kernel/irq/handle.c | 7 +-- + 4 files changed, 90 insertions(+), 24 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -127,19 +127,15 @@ + * + * void add_input_randomness(unsigned int type, unsigned int code, + * unsigned int value); +- * void add_interrupt_randomness(int irq); ++ * void add_interrupt_randomness(int irq, int irq_flags); + * void add_disk_randomness(struct gendisk *disk); + * + * add_input_randomness() uses the input layer interrupt timing, as well as + * the event type information from the hardware. + * +- * add_interrupt_randomness() uses the inter-interrupt timing as random +- * inputs to the entropy pool. Note that not all interrupts are good +- * sources of randomness! For example, the timer interrupts is not a +- * good choice, because the periodicity of the interrupts is too +- * regular, and hence predictable to an attacker. Network Interface +- * Controller interrupts are a better measure, since the timing of the +- * NIC interrupts are more unpredictable. ++ * add_interrupt_randomness() uses the interrupt timing as random ++ * inputs to the entropy pool. Using the cycle counters and the irq source ++ * as inputs, it feeds the randomness roughly once a second. + * + * add_disk_randomness() uses what amounts to the seek time of block + * layer request events, on a per-disk_devt basis, as input to the +@@ -248,6 +244,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_GENERIC_HARDIRQS + # include +@@ -256,6 +253,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -421,7 +419,9 @@ struct entropy_store { + spinlock_t lock; + unsigned add_ptr; + int entropy_count; ++ int entropy_total; + int input_rotate; ++ unsigned int initialized:1; + __u8 last_data[EXTRACT_SIZE]; + }; + +@@ -454,6 +454,10 @@ static struct entropy_store nonblocking_ + .pool = nonblocking_pool_data + }; + ++static __u32 const twist_table[8] = { ++ 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, ++ 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; ++ + /* + * This function adds bytes into the entropy "pool". It does not + * update the entropy estimate. The caller should call +@@ -467,9 +471,6 @@ static struct entropy_store nonblocking_ + static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, + int nbytes, __u8 out[64]) + { +- static __u32 const twist_table[8] = { +- 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, +- 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; + unsigned long i, j, tap1, tap2, tap3, tap4, tap5; + int input_rotate; + int wordmask = r->poolinfo->poolwords - 1; +@@ -528,6 +529,36 @@ static void mix_pool_bytes(struct entrop + mix_pool_bytes_extract(r, in, bytes, NULL); + } + ++struct fast_pool { ++ __u32 pool[4]; ++ unsigned long last; ++ unsigned short count; ++ unsigned char rotate; ++ unsigned char last_timer_intr; ++}; ++ ++/* ++ * This is a fast mixing routine used by the interrupt randomness ++ * collector. It's hardcoded for an 128 bit pool and assumes that any ++ * locks that might be needed are taken by the caller. ++ */ ++static void fast_mix(struct fast_pool *f, const void *in, int nbytes) ++{ ++ const char *bytes = in; ++ __u32 w; ++ unsigned i = f->count; ++ unsigned input_rotate = f->rotate; ++ ++ while (nbytes--) { ++ w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ ++ f->pool[(i + 1) & 3]; ++ f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; ++ input_rotate += (i++ & 3) ? 7 : 14; ++ } ++ f->count = i; ++ f->rotate = input_rotate; ++} ++ + /* + * Credit (or debit) the entropy store with n bits of entropy + */ +@@ -551,6 +582,12 @@ static void credit_entropy_bits(struct e + entropy_count = r->poolinfo->POOLBITS; + r->entropy_count = entropy_count; + ++ if (!r->initialized && nbits > 0) { ++ r->entropy_total += nbits; ++ if (r->entropy_total > 128) ++ r->initialized = 1; ++ } ++ + /* should we wake readers? */ + if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { + wake_up_interruptible(&random_read_wait); +@@ -700,17 +737,48 @@ void add_input_randomness(unsigned int t + } + EXPORT_SYMBOL_GPL(add_input_randomness); + +-void add_interrupt_randomness(int irq) ++static DEFINE_PER_CPU(struct fast_pool, irq_randomness); ++ ++void add_interrupt_randomness(int irq, int irq_flags) + { +- struct timer_rand_state *state; ++ struct entropy_store *r; ++ struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); ++ struct pt_regs *regs = get_irq_regs(); ++ unsigned long now = jiffies; ++ __u32 input[4], cycles = get_cycles(); ++ ++ input[0] = cycles ^ jiffies; ++ input[1] = irq; ++ if (regs) { ++ __u64 ip = instruction_pointer(regs); ++ input[2] = ip; ++ input[3] = ip >> 32; ++ } + +- state = get_timer_rand_state(irq); ++ fast_mix(fast_pool, input, sizeof(input)); + +- if (state == NULL) ++ if ((fast_pool->count & 1023) && ++ !time_after(now, fast_pool->last + HZ)) + return; + +- DEBUG_ENT("irq event %d\n", irq); +- add_timer_randomness(state, 0x100 + irq); ++ fast_pool->last = now; ++ ++ r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; ++ mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool)); ++ /* ++ * If we don't have a valid cycle counter, and we see ++ * back-to-back timer interrupts, then skip giving credit for ++ * any entropy. ++ */ ++ if (cycles == 0) { ++ if (irq_flags & __IRQF_TIMER) { ++ if (fast_pool->last_timer_intr) ++ return; ++ fast_pool->last_timer_intr = 1; ++ } else ++ fast_pool->last_timer_intr = 0; ++ } ++ credit_entropy_bits(r, 1); + } + + #ifdef CONFIG_BLOCK +@@ -970,6 +1038,7 @@ static void init_std_data(struct entropy + + spin_lock_irqsave(&r->lock, flags); + r->entropy_count = 0; ++ r->entropy_total = 0; + spin_unlock_irqrestore(&r->lock, flags); + + now = ktime_get_real(); +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -408,8 +408,6 @@ static irqreturn_t ab3100_irq_handler(in + u32 fatevent; + int err; + +- add_interrupt_randomness(irq); +- + err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, + event_regs, 3); + if (err) +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -52,7 +52,7 @@ extern void rand_initialize_irq(int irq) + + extern void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value); +-extern void add_interrupt_randomness(int irq); ++extern void add_interrupt_randomness(int irq, int irq_flags); + + extern void get_random_bytes(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); +--- a/kernel/irq/handle.c ++++ b/kernel/irq/handle.c +@@ -117,7 +117,7 @@ irqreturn_t + handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) + { + irqreturn_t retval = IRQ_NONE; +- unsigned int random = 0, irq = desc->irq_data.irq; ++ unsigned int flags = 0, irq = desc->irq_data.irq; + + do { + irqreturn_t res; +@@ -145,7 +145,7 @@ handle_irq_event_percpu(struct irq_desc + + /* Fall through to add to randomness */ + case IRQ_HANDLED: +- random |= action->flags; ++ flags |= action->flags; + break; + + default: +@@ -156,8 +156,7 @@ handle_irq_event_percpu(struct irq_desc + action = action->next; + } while (action); + +- if (random & IRQF_SAMPLE_RANDOM) +- add_interrupt_randomness(irq); ++ add_interrupt_randomness(irq, flags); + + if (!noirqdebug) + note_interrupt(irq, desc, retval); diff --git a/queue-3.0/random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch b/queue-3.0/random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch new file mode 100644 index 00000000000..ed6e3a962fb --- /dev/null +++ b/queue-3.0/random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch @@ -0,0 +1,66 @@ +From cf833d0b9937874b50ef2867c4e8badfd64948ce Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 22 Dec 2011 11:36:22 -0800 +Subject: random: Use arch_get_random_int instead of cycle counter if avail + +From: Linus Torvalds + +commit cf833d0b9937874b50ef2867c4e8badfd64948ce upstream. + +We still don't use rdrand in /dev/random, which just seems stupid. We +accept the *cycle*counter* as a random input, but we don't accept +rdrand? That's just broken. + +Sure, people can do things in user space (write to /dev/random, use +rdrand in addition to /dev/random themselves etc etc), but that +*still* seems to be a particularly stupid reason for saying "we +shouldn't bother to try to do better in /dev/random". + +And even if somebody really doesn't trust rdrand as a source of random +bytes, it seems singularly stupid to trust the cycle counter *more*. + +So I'd suggest the attached patch. I'm not going to even bother +arguing that we should add more bits to the entropy estimate, because +that's not the point - I don't care if /dev/random fills up slowly or +not, I think it's just stupid to not use the bits we can get from +rdrand and mix them into the strong randomness pool. + +Link: http://lkml.kernel.org/r/CA%2B55aFwn59N1=m651QAyTy-1gO1noGbK18zwKDwvwqnravA84A@mail.gmail.com +Acked-by: "David S. Miller" +Acked-by: "Theodore Ts'o" +Acked-by: Herbert Xu +Cc: Matt Mackall +Cc: Tony Luck +Cc: Eric Dumazet +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -624,8 +624,8 @@ static struct timer_rand_state input_tim + static void add_timer_randomness(struct timer_rand_state *state, unsigned num) + { + struct { +- cycles_t cycles; + long jiffies; ++ unsigned cycles; + unsigned num; + } sample; + long delta, delta2, delta3; +@@ -637,7 +637,11 @@ static void add_timer_randomness(struct + goto out; + + sample.jiffies = jiffies; +- sample.cycles = get_cycles(); ++ ++ /* Use arch random value, fall back to cycles */ ++ if (!arch_get_random_int(&sample.cycles)) ++ sample.cycles = get_cycles(); ++ + sample.num = num; + mix_pool_bytes(&input_pool, &sample, sizeof(sample)); + diff --git a/queue-3.0/series b/queue-3.0/series index 2f49a9a6032..789cf1af65e 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -11,3 +11,6 @@ alsa-hda-remove-quirk-for-dell-vostro-1015.patch mm-mmu_notifier-fix-freed-page-still-mapped-in-secondary-mmu.patch mac80211-cancel-mesh-path-timer.patch x86-nops-missing-break-resulting-in-incorrect-selection-on-intel.patch +random-add-support-for-architectural-random-hooks.patch +random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch +random-make-add_interrupt_randomness-do-something-sane.patch