From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
To: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: nd <nd@arm.com>, "libc-alpha@sourceware.org" <libc-alpha@sourceware.org>
Subject: Re: [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits
Date: Thu, 7 Mar 2019 17:09:58 +0000 [thread overview]
Message-ID: <DB5PR08MB1030324E236C7205748F2D9C834C0@DB5PR08MB1030.eurprd08.prod.outlook.com> (raw)
Hi Adhemerval,
LGTM with a few minor comments below.
Wilco
include/random-bits.h | 41 ++++++++++++++++++++++++++++++++++++++++
resolv/res_mkquery.c | 19 +++----------------
resolv/res_send.c | 12 ++----------
sysdeps/posix/tempname.c | 19 +++----------------
4 files changed, 49 insertions(+), 42 deletions(-)
create mode 100644 include/random-bits.h
diff --git a/include/random-bits.h b/include/random-bits.h
new file mode 100644
index 0000000000..5ab53450af
--- /dev/null
+++ b/include/random-bits.h
@@ -0,0 +1,41 @@
+/* Fast pseudo-random bits based on clock_gettime.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _RANDOM_BITS_H
+# define _RANDOM_BITS_H
+
+#include <time.h>
+#include <stdint.h>
+
+/* Provides fast pseudo-random bits through clock_gettime. It has unspecified
+ starting time, nano-second accuracy, its randomness is significantly better
+ than gettimeofday, and for mostly architectures it is implemented through
+ vDSO instead of a syscall. Since the source is a system clock, the upper
+ bits will have less entropy. */
+static inline uint32_t
+random_bits (void)
+{
+ struct timespec tv;
+ __clock_gettime (CLOCK_MONOTONIC, &tv);
+ /* Shuffle the lower bits to minimize the clock bias. */
+ uint32_t ret = tv.tv_nsec ^ tv.tv_sec;
+ ret ^= (ret << 24) | (ret >> 8);
+ return ret;
+}
+
+#endif
OK
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 19b8b402c4..dd43d347af 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -82,6 +82,7 @@
* SOFTWARE.
*/
+#include <stdint.h>
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
@@ -92,12 +93,7 @@
#include <string.h>
#include <sys/time.h>
#include <shlib-compat.h>
-
-#include <hp-timing.h>
-#include <stdint.h>
-#if HP_TIMING_AVAIL
-# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; }
-#endif
+#include <random-bits.h>
int
__res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
@@ -120,16 +116,7 @@ __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
/* We randomize the IDs every time. The old code just incremented
by one after the initial randomization which still predictable if
the application does multiple requests. */
- int randombits;
-#ifdef RANDOM_BITS
- RANDOM_BITS (randombits);
-#else
- struct timeval tv;
- __gettimeofday (&tv, NULL);
- randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
-#endif
-
- hp->id = randombits;
+ hp->id = random_bits ();
hp->opcode = op;
hp->rd = (ctx->resp->options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
OK
diff --git a/resolv/res_send.c b/resolv/res_send.c
index fa040c1198..1b59b6080c 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -109,7 +109,7 @@
#include <unistd.h>
#include <kernel-features.h>
#include <libc-diag.h>
-#include <hp-timing.h>
+#include <random-bits.h>
#if PACKETSZ > 65536
#define MAXPACKET PACKETSZ
@@ -309,15 +309,7 @@ nameserver_offset (struct __res_state *statp)
if ((offset & 1) == 0)
{
/* Initialization is required. */
-#if HP_TIMING_AVAIL
- uint64_t ticks;
- HP_TIMING_NOW (ticks);
- offset = ticks;
-#else
- struct timeval tv;
- __gettimeofday (&tv, NULL);
- offset = ((tv.tv_sec << 8) ^ tv.tv_usec);
-#endif
+ offset = random_bits ();
/* The lowest bit is the most random. Preserve it. */
offset <<= 1;
OK
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 2ed39d1a42..5217cb38e1 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -71,22 +71,8 @@
#endif
#ifdef _LIBC
-# include <hp-timing.h>
-# if HP_TIMING_AVAIL
-# define RANDOM_BITS(Var) \
- if (__glibc_unlikely (value == UINT64_C (0))) \
- { \
- /* If this is the first time this function is used initialize \
- the variable we accumulate the value in to some somewhat \
- random value. If we'd not do this programs at startup time \
- might have a reduced set of possible names, at least on slow \
- machines. */ \
- struct timeval tv; \
- __gettimeofday (&tv, NULL); \
- value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
- } \
- HP_TIMING_NOW (Var)
-# endif
+# include <random-bits.h>
+# define RANDOM_BITS(Var) ((Var) = random_bits ())
This define is not used (removed above).
#endif
/* Use the widest available unsigned type if uint64_t is not
@@ -237,6 +223,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
}
#endif
value += random_time_bits ^ __getpid ();
+ value += random_bits () ^ __getpid ();
One of these should be shifted so that it actually increases the number of
random bits.
Note value is static, which looks like a concurrency bug. Making it a local
should work equally well now we've got a better random number.
for (count = 0; count < attempts; value += 7777, ++count)
{
--
2.17.1
next reply other threads:[~2019-03-07 17:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-07 17:09 Wilco Dijkstra [this message]
2019-03-19 16:52 ` [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Adhemerval Zanella
2019-03-20 15:32 ` Wilco Dijkstra
2019-03-20 17:42 ` Adhemerval Zanella
-- strict thread matches above, loose matches on Subject: below --
2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
2019-02-18 21:11 ` [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Adhemerval Zanella
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/libc/involved.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DB5PR08MB1030324E236C7205748F2D9C834C0@DB5PR08MB1030.eurprd08.prod.outlook.com \
--to=wilco.dijkstra@arm.com \
--cc=adhemerval.zanella@linaro.org \
--cc=libc-alpha@sourceware.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).