Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1658990 > unrolled thread
| Started by | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| First post | 2017-06-06 19:50 +0200 |
| Last post | 2017-06-07 14:40 +0200 |
| Articles | 19 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v4 00/13] Unseeded In-Kernel Randomness Fixes "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 19:50 +0200
[PATCH v4 10/13] net/neighbor: use get_random_u32 for 32-bit hash random "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 19:50 +0200
Re: [PATCH v4 10/13] net/neighbor: use get_random_u32 for 32-bit hash random Theodore Ts'o <tytso@mit.edu> - 2017-06-08 05:10 +0200
[PATCH v4 04/13] security/keys: ensure RNG is seeded before use "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 19:50 +0200
Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use Theodore Ts'o <tytso@mit.edu> - 2017-06-08 02:40 +0200
Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-08 03:00 +0200
Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-08 03:10 +0200
[PATCH v4 03/13] random: add get_random_{bytes,u32,u64,int,long,once}_wait family "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 20:00 +0200
Re: [kernel-hardening] [PATCH v4 03/13] random: add get_random_{bytes,u32,u64,int,long,once}_wait family Theodore Ts'o <tytso@mit.edu> - 2017-06-08 02:10 +0200
[PATCH v4 02/13] random: add synchronous API for the urandom pool "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 20:00 +0200
Re: [PATCH v4 02/13] random: add synchronous API for the urandom pool Theodore Ts'o <tytso@mit.edu> - 2017-06-08 02:10 +0200
[PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 20:00 +0200
Re: [kernel-hardening] [PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-08 02:50 +0200
Re: [kernel-hardening] [PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using Theodore Ts'o <tytso@mit.edu> - 2017-06-08 02:50 +0200
[PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-06 20:00 +0200
Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random Theodore Ts'o <tytso@mit.edu> - 2017-06-08 02:30 +0200
Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-08 02:40 +0200
Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-08 02:40 +0200
Re: [PATCH v4 00/13] Unseeded In-Kernel Randomness Fixes "Jason A. Donenfeld" <Jason@zx2c4.com> - 2017-06-07 14:40 +0200
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 19:50 +0200 |
| Subject | [PATCH v4 00/13] Unseeded In-Kernel Randomness Fixes |
| Message-ID | <tPqM9-3tE-3@gated-at.bofh.it> |
As discussed in [1], there is a problem with get_random_bytes being
used before the RNG has actually been seeded. The solution for fixing
this appears to be multi-pronged. One of those prongs involves adding
a simple blocking API so that modules that use the RNG in process
context can just sleep (in an interruptable manner) until the RNG is
ready to be used. This winds up being a very useful API that covers
a few use cases, several of which are included in this patch set.
[1] http://www.openwall.com/lists/kernel-hardening/2017/06/02/2
Changes v3->v4:
- Mark one patch for stable
- Operation ordering on batched entropy invalidation
- Separate out big_key into its own patch to the keys mailing list
- General cleanups
Jason A. Donenfeld (13):
random: invalidate batched entropy after crng init
random: add synchronous API for the urandom pool
random: add get_random_{bytes,u32,u64,int,long,once}_wait family
security/keys: ensure RNG is seeded before use
crypto/rng: ensure that the RNG is ready before using
iscsi: ensure RNG is seeded before use
ceph: ensure RNG is seeded before using
cifs: use get_random_u32 for 32-bit lock random
rhashtable: use get_random_u32 for hash_rnd
net/neighbor: use get_random_u32 for 32-bit hash random
net/route: use get_random_int for random counter
bluetooth/smp: ensure RNG is properly seeded before ECDH use
random: warn when kernel uses unseeded randomness
crypto/rng.c | 6 +-
drivers/char/random.c | 93 +++++++++++++++++++++++++++----
drivers/target/iscsi/iscsi_target_auth.c | 14 ++++-
drivers/target/iscsi/iscsi_target_login.c | 22 +++++---
fs/cifs/cifsfs.c | 2 +-
include/linux/net.h | 2 +
include/linux/once.h | 2 +
include/linux/random.h | 26 +++++++++
lib/Kconfig.debug | 16 ++++++
lib/rhashtable.c | 2 +-
net/bluetooth/hci_request.c | 6 ++
net/bluetooth/smp.c | 18 ++++--
net/ceph/ceph_common.c | 6 +-
net/core/neighbour.c | 3 +-
net/ipv4/route.c | 3 +-
security/keys/encrypted-keys/encrypted.c | 8 ++-
security/keys/key.c | 16 +++---
17 files changed, 198 insertions(+), 47 deletions(-)
--
2.13.0
[toc] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 19:50 +0200 |
| Subject | [PATCH v4 10/13] net/neighbor: use get_random_u32 for 32-bit hash random |
| Message-ID | <tPqMa-3tE-33@gated-at.bofh.it> |
| In reply to | #1658990 |
Using get_random_u32 here is faster, more fitting of the use case, and
just as cryptographically secure. It also has the benefit of providing
better randomness at early boot, which is when many of these structures
are assigned.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: David Miller <davem@davemloft.net>
---
net/core/neighbour.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d274f81fcc2c..9784133b0cdb 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -312,8 +312,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device
static void neigh_get_hash_rnd(u32 *x)
{
- get_random_bytes(x, sizeof(*x));
- *x |= 1;
+ *x = get_random_u32() | 1;
}
static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift)
--
2.13.0
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 05:10 +0200 |
| Subject | Re: [PATCH v4 10/13] net/neighbor: use get_random_u32 for 32-bit hash random |
| Message-ID | <tPVZD-76l-7@gated-at.bofh.it> |
| In reply to | #1658991 |
On Tue, Jun 06, 2017 at 07:48:01PM +0200, Jason A. Donenfeld wrote: > Using get_random_u32 here is faster, more fitting of the use case, and > just as cryptographically secure. It also has the benefit of providing > better randomness at early boot, which is when many of these structures > are assigned. > > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > Cc: David Miller <davem@davemloft.net> Applied to the random.git dev branch, thanks. - Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 19:50 +0200 |
| Subject | [PATCH v4 04/13] security/keys: ensure RNG is seeded before use |
| Message-ID | <tPqMa-3tE-35@gated-at.bofh.it> |
| In reply to | #1658990 |
Otherwise, we might use bad random numbers which, particularly in the
case of IV generation, could be quite bad. It makes sense to use the
synchronous API here, because we're always in process context (as the
code is littered with GFP_KERNEL and the like). However, we can't change
to using a blocking function in key serial allocation, because this will
block booting in some configurations, so here we use the more
appropriate get_random_u32, which will use RDRAND if available.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: David Safford <safford@us.ibm.com>
---
security/keys/encrypted-keys/encrypted.c | 8 +++++---
security/keys/key.c | 16 ++++++++--------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 0010955d7876..d51a28fc5cd5 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -777,10 +777,12 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
__ekey_init(epayload, format, master_desc, datalen);
if (!hex_encoded_iv) {
- get_random_bytes(epayload->iv, ivsize);
+ ret = get_random_bytes_wait(epayload->iv, ivsize);
+ if (unlikely(ret))
+ return ret;
- get_random_bytes(epayload->decrypted_data,
- epayload->decrypted_datalen);
+ ret = get_random_bytes_wait(epayload->decrypted_data,
+ epayload->decrypted_datalen);
} else
ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
return ret;
diff --git a/security/keys/key.c b/security/keys/key.c
index 455c04d80bbb..b72078e532f2 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -134,17 +134,15 @@ void key_user_put(struct key_user *user)
* Allocate a serial number for a key. These are assigned randomly to avoid
* security issues through covert channel problems.
*/
-static inline void key_alloc_serial(struct key *key)
+static inline int key_alloc_serial(struct key *key)
{
struct rb_node *parent, **p;
struct key *xkey;
- /* propose a random serial number and look for a hole for it in the
- * serial number tree */
+ /* propose a non-negative random serial number and look for a hole for
+ * it in the serial number tree */
do {
- get_random_bytes(&key->serial, sizeof(key->serial));
-
- key->serial >>= 1; /* negative numbers are not permitted */
+ key->serial = get_random_u32() >> 1;
} while (key->serial < 3);
spin_lock(&key_serial_lock);
@@ -170,7 +168,7 @@ static inline void key_alloc_serial(struct key *key)
rb_insert_color(&key->serial_node, &key_serial_tree);
spin_unlock(&key_serial_lock);
- return;
+ return 0;
/* we found a key with the proposed serial number - walk the tree from
* that point looking for the next unused serial number */
@@ -314,7 +312,9 @@ struct key *key_alloc(struct key_type *type, const char *desc,
/* publish the key by giving it a serial number */
atomic_inc(&user->nkeys);
- key_alloc_serial(key);
+ ret = key_alloc_serial(key);
+ if (ret < 0)
+ goto security_error;
error:
return key;
--
2.13.0
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 02:40 +0200 |
| Subject | Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use |
| Message-ID | <tPTEu-5rT-17@gated-at.bofh.it> |
| In reply to | #1658992 |
On Tue, Jun 06, 2017 at 07:47:55PM +0200, Jason A. Donenfeld wrote: > -static inline void key_alloc_serial(struct key *key) > +static inline int key_alloc_serial(struct key *key) > @@ -170,7 +168,7 @@ static inline void key_alloc_serial(struct key *key) > rb_insert_color(&key->serial_node, &key_serial_tree); > > spin_unlock(&key_serial_lock); > - return; > + return 0; > > /* we found a key with the proposed serial number - walk the tree from > * that point looking for the next unused serial number */ > @@ -314,7 +312,9 @@ struct key *key_alloc(struct key_type *type, const char *desc, > > /* publish the key by giving it a serial number */ > atomic_inc(&user->nkeys); > - key_alloc_serial(key); > + ret = key_alloc_serial(key); > + if (ret < 0) > + goto security_error; > > error: > return key; I'm guessing you changed key_alloc_serial() to return an int back when you were thinking that you might use get_random_bytes_wait(), which could return -ERESTARTSYS. Now that you're not doing this, but using get_random_u32() instead, there's no point to change the function signature of key_alloc_serial() and add an error check in key_alloc() that will never fail, right? That's just adding a dead code path. Which the compiler can probably optimize away, but why make the code slightly harder to read than necessasry? - Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-08 03:00 +0200 |
| Subject | Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use |
| Message-ID | <tPTXP-5yb-7@gated-at.bofh.it> |
| In reply to | #1660632 |
On Thu, Jun 8, 2017 at 2:31 AM, Theodore Ts'o <tytso@mit.edu> wrote: > I'm guessing you changed key_alloc_serial() to return an int back when > you were thinking that you might use get_random_bytes_wait(), which > could return -ERESTARTSYS. > > Now that you're not doing this, but using get_random_u32() instead, > there's no point to change the function signature of > key_alloc_serial() and add an error check in key_alloc() that will > never fail, right? That's just adding a dead code path. Which the > compiler can probably optimize away, but why make the code slightly > harder to read than necessasry? Good catch, and thanks for reading these so thoroughly that you caught the churn artifacts. Do you want me to clean this up and resubmit, or are you planning on adjusting it in the dev branch?
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-08 03:10 +0200 |
| Subject | Re: [PATCH v4 04/13] security/keys: ensure RNG is seeded before use |
| Message-ID | <tPU7w-5QZ-3@gated-at.bofh.it> |
| In reply to | #1660639 |
On Thu, Jun 8, 2017 at 2:50 AM, Jason A. Donenfeld <Jason@zx2c4.com> wrote: > On Thu, Jun 8, 2017 at 2:31 AM, Theodore Ts'o <tytso@mit.edu> wrote: >> I'm guessing you changed key_alloc_serial() to return an int back when >> you were thinking that you might use get_random_bytes_wait(), which >> could return -ERESTARTSYS. >> >> Now that you're not doing this, but using get_random_u32() instead, >> there's no point to change the function signature of >> key_alloc_serial() and add an error check in key_alloc() that will >> never fail, right? That's just adding a dead code path. Which the >> compiler can probably optimize away, but why make the code slightly >> harder to read than necessasry? > > Good catch, and thanks for reading these so thoroughly that you caught > the churn artifacts. Do you want me to clean this up and resubmit, or > are you planning on adjusting it in the dev branch? Fixed it up here if you just want to grab this instead: https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/linux.git/patch/?id=a0361e55bce30ace529ed8b28bd452e3ac0ee91f
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 20:00 +0200 |
| Subject | [PATCH v4 03/13] random: add get_random_{bytes,u32,u64,int,long,once}_wait family |
| Message-ID | <tPqVQ-3xj-9@gated-at.bofh.it> |
| In reply to | #1658990 |
These functions are simple convenience wrappers that call
wait_for_random_bytes before calling the respective get_random_*
function.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
include/linux/net.h | 2 ++
include/linux/once.h | 2 ++
include/linux/random.h | 25 +++++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/include/linux/net.h b/include/linux/net.h
index abcfa46a2bd9..dda2cc939a53 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -274,6 +274,8 @@ do { \
#define net_get_random_once(buf, nbytes) \
get_random_once((buf), (nbytes))
+#define net_get_random_once_wait(buf, nbytes) \
+ get_random_once_wait((buf), (nbytes))
int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec,
size_t num, size_t len);
diff --git a/include/linux/once.h b/include/linux/once.h
index 285f12cb40e6..9c98aaa87cbc 100644
--- a/include/linux/once.h
+++ b/include/linux/once.h
@@ -53,5 +53,7 @@ void __do_once_done(bool *done, struct static_key *once_key,
#define get_random_once(buf, nbytes) \
DO_ONCE(get_random_bytes, (buf), (nbytes))
+#define get_random_once_wait(buf, nbytes) \
+ DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \
#endif /* _LINUX_ONCE_H */
diff --git a/include/linux/random.h b/include/linux/random.h
index e29929347c95..4aecc339558d 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -58,6 +58,31 @@ static inline unsigned long get_random_long(void)
#endif
}
+/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
+ * Returns the result of the call to wait_for_random_bytes. */
+static inline int get_random_bytes_wait(void *buf, int nbytes)
+{
+ int ret = wait_for_random_bytes();
+ if (unlikely(ret))
+ return ret;
+ get_random_bytes(buf, nbytes);
+ return 0;
+}
+
+#define declare_get_random_var_wait(var) \
+ static inline int get_random_ ## var ## _wait(var *out) { \
+ int ret = wait_for_random_bytes(); \
+ if (unlikely(ret)) \
+ return ret; \
+ *out = get_random_ ## var(); \
+ return 0; \
+ }
+declare_get_random_var_wait(u32)
+declare_get_random_var_wait(u64)
+declare_get_random_var_wait(int)
+declare_get_random_var_wait(long)
+#undef declare_get_random_var
+
unsigned long randomize_page(unsigned long start, unsigned long range);
u32 prandom_u32(void);
--
2.13.0
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 02:10 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 03/13] random: add get_random_{bytes,u32,u64,int,long,once}_wait family |
| Message-ID | <tPTbs-5gQ-23@gated-at.bofh.it> |
| In reply to | #1658995 |
On Tue, Jun 06, 2017 at 07:47:54PM +0200, Jason A. Donenfeld wrote: > These functions are simple convenience wrappers that call > wait_for_random_bytes before calling the respective get_random_* > function. > > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Thanks, applied to the dev branch. - Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 20:00 +0200 |
| Subject | [PATCH v4 02/13] random: add synchronous API for the urandom pool |
| Message-ID | <tPqVR-3xj-31@gated-at.bofh.it> |
| In reply to | #1658990 |
This enables users of get_random_{bytes,u32,u64,int,long} to wait until
the pool is ready before using this function, in case they actually want
to have reliable randomness.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
drivers/char/random.c | 41 +++++++++++++++++++++++++++++++----------
include/linux/random.h | 1 +
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 2291e6224ed3..36cdb2406610 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -851,11 +851,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
spin_unlock_irqrestore(&primary_crng.lock, flags);
}
-static inline void crng_wait_ready(void)
-{
- wait_event_interruptible(crng_init_wait, crng_ready());
-}
-
static void _extract_crng(struct crng_state *crng,
__u8 out[CHACHA20_BLOCK_SIZE])
{
@@ -1473,7 +1468,10 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
* number of good random numbers, suitable for key generation, seeding
* TCP sequence numbers, etc. It does not rely on the hardware random
* number generator. For random bytes direct from the hardware RNG
- * (when available), use get_random_bytes_arch().
+ * (when available), use get_random_bytes_arch(). In order to ensure
+ * that the randomness provided by this function is okay, the function
+ * wait_for_random_bytes() should be called and return 0 at least once
+ * at any point prior.
*/
void get_random_bytes(void *buf, int nbytes)
{
@@ -1503,6 +1501,24 @@ void get_random_bytes(void *buf, int nbytes)
EXPORT_SYMBOL(get_random_bytes);
/*
+ * Wait for the urandom pool to be seeded and thus guaranteed to supply
+ * cryptographically secure random numbers. This applies to: the /dev/urandom
+ * device, the get_random_bytes function, and the get_random_{u32,u64,int,long}
+ * family of functions. Using any of these functions without first calling
+ * this function forfeits the guarantee of security.
+ *
+ * Returns: 0 if the urandom pool has been seeded.
+ * -ERESTARTSYS if the function was interrupted by a signal.
+ */
+int wait_for_random_bytes(void)
+{
+ if (likely(crng_ready()))
+ return 0;
+ return wait_event_interruptible(crng_init_wait, crng_ready());
+}
+EXPORT_SYMBOL(wait_for_random_bytes);
+
+/*
* Add a callback function that will be invoked when the nonblocking
* pool is initialised.
*
@@ -1856,6 +1872,8 @@ const struct file_operations urandom_fops = {
SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
unsigned int, flags)
{
+ int ret;
+
if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
return -EINVAL;
@@ -1868,9 +1886,9 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
if (!crng_ready()) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
- crng_wait_ready();
- if (signal_pending(current))
- return -ERESTARTSYS;
+ ret = wait_for_random_bytes();
+ if (unlikely(ret))
+ return ret;
}
return urandom_read(NULL, buf, count, NULL);
}
@@ -2031,7 +2049,10 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_
/*
* Get a random word for internal kernel use only. The quality of the random
* number is either as good as RDRAND or as good as /dev/urandom, with the
- * goal of being quite fast and not depleting entropy.
+ * goal of being quite fast and not depleting entropy. In order to ensure
+ * that the randomness provided by this function is okay, the function
+ * wait_for_random_bytes() should be called and return 0 at least once
+ * at any point prior.
*/
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
u64 get_random_u64(void)
diff --git a/include/linux/random.h b/include/linux/random.h
index ed5c3838780d..e29929347c95 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -34,6 +34,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy;
extern void get_random_bytes(void *buf, int nbytes);
+extern int wait_for_random_bytes(void);
extern int add_random_ready_callback(struct random_ready_callback *rdy);
extern void del_random_ready_callback(struct random_ready_callback *rdy);
extern void get_random_bytes_arch(void *buf, int nbytes);
--
2.13.0
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 02:10 +0200 |
| Subject | Re: [PATCH v4 02/13] random: add synchronous API for the urandom pool |
| Message-ID | <tPTbu-5gQ-97@gated-at.bofh.it> |
| In reply to | #1659001 |
On Tue, Jun 06, 2017 at 07:47:53PM +0200, Jason A. Donenfeld wrote:
> This enables users of get_random_{bytes,u32,u64,int,long} to wait until
> the pool is ready before using this function, in case they actually want
> to have reliable randomness.
>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Thanks, applied for the dev branch of random.git. (I changed the
patch summary slightly; it now reads: "random: add
wait_for_random_bytes() API").
- Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 20:00 +0200 |
| Subject | [PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using |
| Message-ID | <tPqVR-3xj-33@gated-at.bofh.it> |
| In reply to | #1658990 |
Otherwise, we might be seeding the RNG using bad randomness, which is dangerous. The one use of this function from within the kernel -- not from userspace -- is being removed (keys/big_key), so that call site isn't relevant in assessing this. Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- crypto/rng.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/rng.c b/crypto/rng.c index f46dac5288b9..e042437e64b4 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -48,12 +48,14 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen) if (!buf) return -ENOMEM; - get_random_bytes(buf, slen); + err = get_random_bytes_wait(buf, slen); + if (err) + goto out; seed = buf; } err = crypto_rng_alg(tfm)->seed(tfm, seed, slen); - +out: kzfree(buf); return err; } -- 2.13.0
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-08 02:50 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using |
| Message-ID | <tPTO9-5uW-5@gated-at.bofh.it> |
| In reply to | #1659002 |
On Thu, Jun 8, 2017 at 2:41 AM, Theodore Ts'o <tytso@mit.edu> wrote: > The use in keys/big_key is _being_ removed, so this commit is > dependent on that commit landing, correct? (Order matters, because > otherwise we don't want to potentially screw up doing a kernel bisect > and causing their kernel to deadlock during the boot while they are > trying to track down an unreleated problem.) Yes. It's actually landing with get_random_bytes, to avoid a dependency problem when merging. After these both lands, I'll submit a third changing that over to get_random_bytes_wait in the right place.
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 02:50 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 05/13] crypto/rng: ensure that the RNG is ready before using |
| Message-ID | <tPTO9-5uW-7@gated-at.bofh.it> |
| In reply to | #1659002 |
On Tue, Jun 06, 2017 at 07:47:56PM +0200, Jason A. Donenfeld wrote:
> Otherwise, we might be seeding the RNG using bad randomness, which is
> dangerous. The one use of this function from within the kernel -- not
> from userspace -- is being removed (keys/big_key), so that call site
> isn't relevant in assessing this.
The use in keys/big_key is _being_ removed, so this commit is
dependent on that commit landing, correct? (Order matters, because
otherwise we don't want to potentially screw up doing a kernel bisect
and causing their kernel to deadlock during the boot while they are
trying to track down an unreleated problem.)
- Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-06 20:00 +0200 |
| Subject | [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random |
| Message-ID | <tPqVR-3xj-51@gated-at.bofh.it> |
| In reply to | #1658990 |
Using get_random_u32 here is faster, more fitting of the use case, and
just as cryptographically secure. It also has the benefit of providing
better randomness at early boot, which is sometimes when this is used.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Steve French <sfrench@samba.org>
---
fs/cifs/cifsfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9a1667e0e8d6..fe0c8dcc7dc7 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1359,7 +1359,7 @@ init_cifs(void)
spin_lock_init(&cifs_tcp_ses_lock);
spin_lock_init(&GlobalMid_Lock);
- get_random_bytes(&cifs_lock_secret, sizeof(cifs_lock_secret));
+ cifs_lock_secret = get_random_u32();
if (cifs_max_pending < 2) {
cifs_max_pending = 2;
--
2.13.0
[toc] | [prev] | [next] | [standalone]
| From | Theodore Ts'o <tytso@mit.edu> |
|---|---|
| Date | 2017-06-08 02:30 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random |
| Message-ID | <tPTuN-5p2-11@gated-at.bofh.it> |
| In reply to | #1659009 |
On Tue, Jun 06, 2017 at 07:47:59PM +0200, Jason A. Donenfeld wrote: > Using get_random_u32 here is faster, more fitting of the use case, and > just as cryptographically secure. It also has the benefit of providing > better randomness at early boot, which is sometimes when this is used. > > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > Cc: Steve French <sfrench@samba.org> There's a bigger problem here, which is that cifs_lock_secret is a 32-bit value which is being used to obscure flock->fl_owner before it is sent across the wire. But flock->fl_owner is a pointer to the struct file *, so 64-bit architecture, the high 64-bits of a kernel pointer is being exposed to anyone using tcpdump. (Oops, I'm showing my age; I guess all the cool kids are using Wireshark these days.) Worse, the obscuring is being done using XOR. How an active attacker might be able to trivially reverse engineer the 32-bit "secret" is left as an exercise to the reader. The bottom line is if the goal is to hide the memory location of a struct file from an attacker, cifs_lock_secret is about as useful as a TSA agent doing security theatre at an airport. Which is to say, it makes the civilians feel good. :-) BTW, Jason, this is why it's *good* to audit all of the uses of get_random_bytes(). It only took me about 30 seconds in the first patch in your series that changes a caller of get_random_bytes(), and look what I was able to find by just taking a quick look. Not waiting for the CRNG to be fully initialized is the *least* of its problems. Anyway, I'll include this commit in the dev branch of the random tree, since it's not going to make things worse. - Ted
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-08 02:40 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random |
| Message-ID | <tPTEt-5rT-5@gated-at.bofh.it> |
| In reply to | #1660623 |
On Thu, Jun 8, 2017 at 2:25 AM, Theodore Ts'o <tytso@mit.edu> wrote: > There's a bigger problem here, which is that cifs_lock_secret is a > 32-bit value which is being used to obscure flock->fl_owner before it > is sent across the wire. But flock->fl_owner is a pointer to the > struct file *, so 64-bit architecture, the high 64-bits of a kernel > pointer is being exposed to anyone using tcpdump. (Oops, I'm showing > my age; I guess all the cool kids are using Wireshark these days.) > > Worse, the obscuring is being done using XOR. How an active attacker > might be able to trivially reverse engineer the 32-bit "secret" is > left as an exercise to the reader. The bottom line is if the goal is > to hide the memory location of a struct file from an attacker, > cifs_lock_secret is about as useful as a TSA agent doing security > theatre at an airport. Which is to say, it makes the civilians feel > good. :-) High five for taking the deep dive and actually reading how this all works. Nice bug! > Not waiting > for the CRNG to be fully initialized is the *least* of its problems. The kernel is vast and filled with tons of bugs of many sorts. On this reasoning, maybe I should spend my time auditing web apps instead, which are usually the "front door" of bugs? I like the puzzles of random.c. I also had a real world need for wait_for_random_bytes() in a module I'm writing. But anyway, your general point is a really good one. Tons of callers of the random functions are doing it wrong in one way or another. Spending time looking at those is probably a good idea... > Anyway, I'll include this commit in the dev branch of the random tree, > since it's not going to make things worse. Great, thanks.
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-08 02:40 +0200 |
| Subject | Re: [kernel-hardening] [PATCH v4 08/13] cifs: use get_random_u32 for 32-bit lock random |
| Message-ID | <tPTEt-5rT-9@gated-at.bofh.it> |
| In reply to | #1660623 |
On Thu, Jun 8, 2017 at 2:25 AM, Theodore Ts'o <tytso@mit.edu> wrote: > There's a bigger problem here, which is that cifs_lock_secret is a > 32-bit value which is being used to obscure flock->fl_owner before it > is sent across the wire. But flock->fl_owner is a pointer to the > struct file *, so 64-bit architecture, the high 64-bits of a kernel > pointer is being exposed to anyone using tcpdump. (Oops, I'm showing > my age; I guess all the cool kids are using Wireshark these days.) > > Worse, the obscuring is being done using XOR. How an active attacker > might be able to trivially reverse engineer the 32-bit "secret" is > left as an exercise to the reader. The bottom line is if the goal is > to hide the memory location of a struct file from an attacker, > cifs_lock_secret is about as useful as a TSA agent doing security > theatre at an airport. Which is to say, it makes the civilians feel > good. :-) High five for taking the deep dive and actually reading how this all works. Nice bug! > Not waiting > for the CRNG to be fully initialized is the *least* of its problems. The kernel is vast and filled with tons of bugs of many sorts. On this reasoning, maybe I should spend my time auditing web apps instead, which are usually the "front door" of bugs? I like the puzzles of random.c. I also had a real world need for wait_for_random_bytes() in a module I'm writing. But anyway, your general point is a really good one. Tons of callers of the random functions are doing it wrong in one way or another. Spending time looking at those is probably a good idea... > Anyway, I'll include this commit in the dev branch of the random tree, > since it's not going to make things worse. Great, thanks.
[toc] | [prev] | [next] | [standalone]
| From | "Jason A. Donenfeld" <Jason@zx2c4.com> |
|---|---|
| Date | 2017-06-07 14:40 +0200 |
| Message-ID | <tPIpJ-6D4-47@gated-at.bofh.it> |
| In reply to | #1658990 |
Hi Ted, Could I get your Signed-off-by on this patchset, so that somebody can add it to their tree? Thanks, Jason
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web