[PATCH v2] timekeeping: contribute wall clock to rng on time change

Jason A. Donenfeld posted 1 patch 3 years, 10 months ago
There is a newer version of this series
kernel/time/timekeeping.c | 5 +++++
1 file changed, 5 insertions(+)
[PATCH v2] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 10 months ago
The rng's random_init() function contributes the real time to the rng at
boot time, so that events can at least start in relation to something
particular in the real world. But this clock might not yet be set that
point in boot, so nothing is contributed. In addition, the relation
between minor clock changes from, say, NTP, and the cycle counter is
potentially useful entropic data.

This commit addresses this by mixing in a time stamp on calls to
settimeofday and adjtimex. No entropy is credited in doing so, so it
doesn't make initialization faster, but it is still useful input to
have.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 kernel/time/timekeeping.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8e4b3c32fcf9..89b894b3ede8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -23,6 +23,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/random.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
@@ -1331,6 +1332,8 @@ int do_settimeofday64(const struct timespec64 *ts)
 		goto out;
 	}
 
+	add_device_randomness(&ts, sizeof(ts));
+
 	tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
 
 	tk_set_xtime(tk, ts);
@@ -2430,6 +2433,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	ret = timekeeping_validate_timex(txc);
 	if (ret)
 		return ret;
+	add_device_randomness(txc, sizeof(*txc));
 
 	if (txc->modes & ADJ_SETOFFSET) {
 		struct timespec64 delta;
@@ -2447,6 +2451,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	audit_ntp_init(&ad);
 
 	ktime_get_real_ts64(&ts);
+	add_device_randomness(&ts, sizeof(ts));
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
-- 
2.35.1
Re: [PATCH v2] timekeeping: contribute wall clock to rng on time change
Posted by Eric Biggers 3 years, 10 months ago
On Thu, Jun 23, 2022 at 08:05:55PM +0200, Jason A. Donenfeld wrote:
> The rng's random_init() function contributes the real time to the rng at
> boot time, so that events can at least start in relation to something
> particular in the real world. But this clock might not yet be set that
> point in boot, so nothing is contributed. In addition, the relation
> between minor clock changes from, say, NTP, and the cycle counter is
> potentially useful entropic data.
> 
> This commit addresses this by mixing in a time stamp on calls to
> settimeofday and adjtimex. No entropy is credited in doing so, so it
> doesn't make initialization faster, but it is still useful input to
> have.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  kernel/time/timekeeping.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index 8e4b3c32fcf9..89b894b3ede8 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -23,6 +23,7 @@
>  #include <linux/pvclock_gtod.h>
>  #include <linux/compiler.h>
>  #include <linux/audit.h>
> +#include <linux/random.h>
>  
>  #include "tick-internal.h"
>  #include "ntp_internal.h"
> @@ -1331,6 +1332,8 @@ int do_settimeofday64(const struct timespec64 *ts)
>  		goto out;
>  	}
>  
> +	add_device_randomness(&ts, sizeof(ts));
> +
>  	tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));

This is now nested inside:

	raw_spin_lock_irqsave(&timekeeper_lock, flags);
	write_seqcount_begin(&tk_core.seq);

Could there be a deadlock if random_get_entropy() in add_device_randomness()
falls back to reading the monotonic clock?

- Eric
Re: [PATCH v2] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 10 months ago
On Thu, Jun 23, 2022 at 8:53 PM Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Thu, Jun 23, 2022 at 08:05:55PM +0200, Jason A. Donenfeld wrote:
> > The rng's random_init() function contributes the real time to the rng at
> > boot time, so that events can at least start in relation to something
> > particular in the real world. But this clock might not yet be set that
> > point in boot, so nothing is contributed. In addition, the relation
> > between minor clock changes from, say, NTP, and the cycle counter is
> > potentially useful entropic data.
> >
> > This commit addresses this by mixing in a time stamp on calls to
> > settimeofday and adjtimex. No entropy is credited in doing so, so it
> > doesn't make initialization faster, but it is still useful input to
> > have.
> >
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> > ---
> >  kernel/time/timekeeping.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> > index 8e4b3c32fcf9..89b894b3ede8 100644
> > --- a/kernel/time/timekeeping.c
> > +++ b/kernel/time/timekeeping.c
> > @@ -23,6 +23,7 @@
> >  #include <linux/pvclock_gtod.h>
> >  #include <linux/compiler.h>
> >  #include <linux/audit.h>
> > +#include <linux/random.h>
> >
> >  #include "tick-internal.h"
> >  #include "ntp_internal.h"
> > @@ -1331,6 +1332,8 @@ int do_settimeofday64(const struct timespec64 *ts)
> >               goto out;
> >       }
> >
> > +     add_device_randomness(&ts, sizeof(ts));
> > +
> >       tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
>
> This is now nested inside:
>
>         raw_spin_lock_irqsave(&timekeeper_lock, flags);
>         write_seqcount_begin(&tk_core.seq);
>
> Could there be a deadlock if random_get_entropy() in add_device_randomness()
> falls back to reading the monotonic clock?

Also nice find as the raw_spin_lock itself is problematic on RT,
because add_device_randomness can take a normal one. I'll do some
hoisting.

Jason
[PATCH v3] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 10 months ago
The rng's random_init() function contributes the real time to the rng at
boot time, so that events can at least start in relation to something
particular in the real world. But this clock might not yet be set that
point in boot, so nothing is contributed. In addition, the relation
between minor clock changes from, say, NTP, and the cycle counter is
potentially useful entropic data.

This commit addresses this by mixing in a time stamp on calls to
settimeofday and adjtimex. No entropy is credited in doing so, so it
doesn't make initialization faster, but it is still useful input to
have.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 kernel/time/timekeeping.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8e4b3c32fcf9..49ee8ef16544 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -23,6 +23,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/random.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
@@ -1343,8 +1344,10 @@ int do_settimeofday64(const struct timespec64 *ts)
 	/* Signal hrtimers about time change */
 	clock_was_set(CLOCK_SET_WALL);
 
-	if (!ret)
+	if (!ret) {
 		audit_tk_injoffset(ts_delta);
+		add_device_randomness(&ts, sizeof(ts));
+	}
 
 	return ret;
 }
@@ -2430,6 +2433,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	ret = timekeeping_validate_timex(txc);
 	if (ret)
 		return ret;
+	add_device_randomness(txc, sizeof(*txc));
 
 	if (txc->modes & ADJ_SETOFFSET) {
 		struct timespec64 delta;
@@ -2447,6 +2451,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	audit_ntp_init(&ad);
 
 	ktime_get_real_ts64(&ts);
+	add_device_randomness(&ts, sizeof(ts));
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
-- 
2.35.1
Re: [PATCH v3] timekeeping: contribute wall clock to rng on time change
Posted by Eric Biggers 3 years, 10 months ago
On Thu, Jun 23, 2022 at 09:00:14PM +0200, Jason A. Donenfeld wrote:
> The rng's random_init() function contributes the real time to the rng at
> boot time, so that events can at least start in relation to something
> particular in the real world. But this clock might not yet be set that
> point in boot, so nothing is contributed. In addition, the relation
> between minor clock changes from, say, NTP, and the cycle counter is
> potentially useful entropic data.
> 
> This commit addresses this by mixing in a time stamp on calls to
> settimeofday and adjtimex. No entropy is credited in doing so, so it
> doesn't make initialization faster, but it is still useful input to
> have.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  kernel/time/timekeeping.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index 8e4b3c32fcf9..49ee8ef16544 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -23,6 +23,7 @@
>  #include <linux/pvclock_gtod.h>
>  #include <linux/compiler.h>
>  #include <linux/audit.h>
> +#include <linux/random.h>
>  
>  #include "tick-internal.h"
>  #include "ntp_internal.h"
> @@ -1343,8 +1344,10 @@ int do_settimeofday64(const struct timespec64 *ts)
>  	/* Signal hrtimers about time change */
>  	clock_was_set(CLOCK_SET_WALL);
>  
> -	if (!ret)
> +	if (!ret) {
>  		audit_tk_injoffset(ts_delta);
> +		add_device_randomness(&ts, sizeof(ts));
> +	}

It should be:

add_device_randomness(ts, sizeof(*ts));

- Eric
Re: [PATCH v3] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 10 months ago
On Thu, Jun 23, 2022 at 9:10 PM Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Thu, Jun 23, 2022 at 09:00:14PM +0200, Jason A. Donenfeld wrote:
> > The rng's random_init() function contributes the real time to the rng at
> > boot time, so that events can at least start in relation to something
> > particular in the real world. But this clock might not yet be set that
> > point in boot, so nothing is contributed. In addition, the relation
> > between minor clock changes from, say, NTP, and the cycle counter is
> > potentially useful entropic data.
> >
> > This commit addresses this by mixing in a time stamp on calls to
> > settimeofday and adjtimex. No entropy is credited in doing so, so it
> > doesn't make initialization faster, but it is still useful input to
> > have.
> >
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> > ---
> >  kernel/time/timekeeping.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> > index 8e4b3c32fcf9..49ee8ef16544 100644
> > --- a/kernel/time/timekeeping.c
> > +++ b/kernel/time/timekeeping.c
> > @@ -23,6 +23,7 @@
> >  #include <linux/pvclock_gtod.h>
> >  #include <linux/compiler.h>
> >  #include <linux/audit.h>
> > +#include <linux/random.h>
> >
> >  #include "tick-internal.h"
> >  #include "ntp_internal.h"
> > @@ -1343,8 +1344,10 @@ int do_settimeofday64(const struct timespec64 *ts)
> >       /* Signal hrtimers about time change */
> >       clock_was_set(CLOCK_SET_WALL);
> >
> > -     if (!ret)
> > +     if (!ret) {
> >               audit_tk_injoffset(ts_delta);
> > +             add_device_randomness(&ts, sizeof(ts));
> > +     }
>
> It should be:
>
> add_device_randomness(ts, sizeof(*ts));

This simple patch... I swear I know C, I promise...

Thanks again, and sorry.

Jason
[PATCH v4] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 10 months ago
The rng's random_init() function contributes the real time to the rng at
boot time, so that events can at least start in relation to something
particular in the real world. But this clock might not yet be set that
point in boot, so nothing is contributed. In addition, the relation
between minor clock changes from, say, NTP, and the cycle counter is
potentially useful entropic data.

This commit addresses this by mixing in a time stamp on calls to
settimeofday and adjtimex. No entropy is credited in doing so, so it
doesn't make initialization faster, but it is still useful input to
have.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 kernel/time/timekeeping.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8e4b3c32fcf9..f72b9f1de178 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -23,6 +23,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/random.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
@@ -1343,8 +1344,10 @@ int do_settimeofday64(const struct timespec64 *ts)
 	/* Signal hrtimers about time change */
 	clock_was_set(CLOCK_SET_WALL);
 
-	if (!ret)
+	if (!ret) {
 		audit_tk_injoffset(ts_delta);
+		add_device_randomness(ts, sizeof(*ts));
+	}
 
 	return ret;
 }
@@ -2430,6 +2433,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	ret = timekeeping_validate_timex(txc);
 	if (ret)
 		return ret;
+	add_device_randomness(txc, sizeof(*txc));
 
 	if (txc->modes & ADJ_SETOFFSET) {
 		struct timespec64 delta;
@@ -2447,6 +2451,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	audit_ntp_init(&ad);
 
 	ktime_get_real_ts64(&ts);
+	add_device_randomness(&ts, sizeof(ts));
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
-- 
2.35.1
Re: [PATCH v4] timekeeping: contribute wall clock to rng on time change
Posted by Eric Biggers 3 years, 10 months ago
On Thu, Jun 23, 2022 at 09:12:49PM +0200, Jason A. Donenfeld wrote:
> The rng's random_init() function contributes the real time to the rng at
> boot time, so that events can at least start in relation to something
> particular in the real world. But this clock might not yet be set that
> point in boot, so nothing is contributed. In addition, the relation
> between minor clock changes from, say, NTP, and the cycle counter is
> potentially useful entropic data.
> 
> This commit addresses this by mixing in a time stamp on calls to
> settimeofday and adjtimex. No entropy is credited in doing so, so it
> doesn't make initialization faster, but it is still useful input to
> have.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  kernel/time/timekeeping.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)

Reviewed-by: Eric Biggers <ebiggers@google.com>

- Eric
Re: [PATCH v4] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 9 months ago
Hi Thomas,

On Thu, Jun 23, 2022 at 12:36:23PM -0700, Eric Biggers wrote:
> On Thu, Jun 23, 2022 at 09:12:49PM +0200, Jason A. Donenfeld wrote:
> > The rng's random_init() function contributes the real time to the rng at
> > boot time, so that events can at least start in relation to something
> > particular in the real world. But this clock might not yet be set that
> > point in boot, so nothing is contributed. In addition, the relation
> > between minor clock changes from, say, NTP, and the cycle counter is
> > potentially useful entropic data.
> > 
> > This commit addresses this by mixing in a time stamp on calls to
> > settimeofday and adjtimex. No entropy is credited in doing so, so it
> > doesn't make initialization faster, but it is still useful input to
> > have.
> > 
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> > ---
> >  kernel/time/timekeeping.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> Reviewed-by: Eric Biggers <ebiggers@google.com>

Thought I should bump this patch in case you missed it.

Jason
[PATCH v4 RESEND] timekeeping: contribute wall clock to rng on time change
Posted by Jason A. Donenfeld 3 years, 9 months ago
The rng's random_init() function contributes the real time to the rng at
boot time, so that events can at least start in relation to something
particular in the real world. But this clock might not yet be set that
point in boot, so nothing is contributed. In addition, the relation
between minor clock changes from, say, NTP, and the cycle counter is
potentially useful entropic data.

This commit addresses this by mixing in a time stamp on calls to
settimeofday and adjtimex. No entropy is credited in doing so, so it
doesn't make initialization faster, but it is still useful input to
have.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 kernel/time/timekeeping.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8e4b3c32fcf9..f72b9f1de178 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -23,6 +23,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/random.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
@@ -1343,8 +1344,10 @@ int do_settimeofday64(const struct timespec64 *ts)
 	/* Signal hrtimers about time change */
 	clock_was_set(CLOCK_SET_WALL);
 
-	if (!ret)
+	if (!ret) {
 		audit_tk_injoffset(ts_delta);
+		add_device_randomness(ts, sizeof(*ts));
+	}
 
 	return ret;
 }
@@ -2430,6 +2433,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	ret = timekeeping_validate_timex(txc);
 	if (ret)
 		return ret;
+	add_device_randomness(txc, sizeof(*txc));
 
 	if (txc->modes & ADJ_SETOFFSET) {
 		struct timespec64 delta;
@@ -2447,6 +2451,7 @@ int do_adjtimex(struct __kernel_timex *txc)
 	audit_ntp_init(&ad);
 
 	ktime_get_real_ts64(&ts);
+	add_device_randomness(&ts, sizeof(ts));
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
-- 
2.35.1
Re: [PATCH v4 RESEND] timekeeping: contribute wall clock to rng on time change
Posted by Thomas Gleixner 3 years, 9 months ago
On Sun, Jul 17 2022 at 23:53, Jason A. Donenfeld wrote:

> The rng's random_init() function contributes the real time to the rng at
> boot time, so that events can at least start in relation to something
> particular in the real world. But this clock might not yet be set that
> point in boot, so nothing is contributed. In addition, the relation
> between minor clock changes from, say, NTP, and the cycle counter is
> potentially useful entropic data.
>
> This commit addresses this by mixing in a time stamp on calls to
> settimeofday and adjtimex. No entropy is credited in doing so, so it
> doesn't make initialization faster, but it is still useful input to
> have.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Reviewed-by: Eric Biggers <ebiggers@google.com>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>