]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Aug 2012 19:37:08 +0000 (12:37 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Aug 2012 19:37:08 +0000 (12:37 -0700)
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

queue-3.0/random-add-support-for-architectural-random-hooks.patch [new file with mode: 0644]
queue-3.0/random-make-add_interrupt_randomness-do-something-sane.patch [new file with mode: 0644]
queue-3.0/random-use-arch_get_random_int-instead-of-cycle-counter-if-avail.patch [new file with mode: 0644]
queue-3.0/series

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 (file)
index 0000000..e599d05
--- /dev/null
@@ -0,0 +1,95 @@
+From 63d77173266c1791f1553e9e8ccea65dc87c4485 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@zytor.com>
+Date: Sun, 31 Jul 2011 13:54:50 -0700
+Subject: random: Add support for architectural random hooks
+
+From: "H. Peter Anvin" <hpa@zytor.com>
+
+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 <hpa@linux.intel.com>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Cc: Matt Mackall <mpm@selenic.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <asm/archrandom.h>
++#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 (file)
index 0000000..8f67be5
--- /dev/null
@@ -0,0 +1,279 @@
+From 775f4b297b780601e61787b766f306ed3e1d23eb Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 2 Jul 2012 07:52:16 -0400
+Subject: random: make 'add_interrupt_randomness()' do something sane
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <ewust@umich.edu>
+Reported-by: Eric Wustrow <ewust@umich.edu>
+Reported-by: Nadia Heninger <nadiah@cs.ucsd.edu>
+Reported-by: Zakir Durumeric <zakir@umich.edu>
+Reported-by: J. Alex Halderman <jhalderm@umich.edu>.
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/percpu.h>
+ #include <linux/cryptohash.h>
+ #include <linux/fips.h>
++#include <linux/ptrace.h>
+ #ifdef CONFIG_GENERIC_HARDIRQS
+ # include <linux/irq.h>
+@@ -256,6 +253,7 @@
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+ #include <asm/irq.h>
++#include <asm/irq_regs.h>
+ #include <asm/io.h>
+ /*
+@@ -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 (file)
index 0000000..ed6e3a9
--- /dev/null
@@ -0,0 +1,66 @@
+From cf833d0b9937874b50ef2867c4e8badfd64948ce Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+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 <torvalds@linux-foundation.org>
+
+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" <davem@davemloft.net>
+Acked-by: "Theodore Ts'o" <tytso@mit.edu>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Matt Mackall <mpm@selenic.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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));
index 2f49a9a60323489fba6301cd8a3dbeab324d8b89..789cf1af65e918bf87a1835e3437feab6b5e263f 100644 (file)
@@ -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