Re: [Qemu-devel] [PATCH v5] linux-user: Let user specify random seed

2014-10-28 Thread Magnus Reftel
On Thu, Oct 23, 2014 at 12:03 PM, Riku Voipio riku.voi...@iki.fi wrote:
 On Wed, Oct 22, 2014 at 03:17:33PM +0200, Magnus Reftel wrote:
 Ping.
 http://patchwork.ozlabs.org/patch/399483/

 Applied to linux-user que, thanks

Thanks!

BR
Magnus Reftel



Re: [Qemu-devel] [PATCH v5] linux-user: Let user specify random seed

2014-10-22 Thread Magnus Reftel
On Tue, Oct 14, 2014 at 5:18 PM, Magnus Reftel ref...@spotify.com wrote:
 linux-user uses the rand function for generating the value of the AT_RANDOM 
 elf
 aux vector entry, and explicitly seeds the random number generator with the
 current time. This makes it impossible to reproduce runs that use the 
 AT_RANDOM
 bytes.

 This patch adds a command line option and a matching environment variable for
 setting the random seed, so that the AT_RANDOM values can be predictable when
 the user chooses. The default is still to seed the random number generator
 with the current time.

 The difference from version 4 of the patch is only the addition of the line
   Reviewed-by: Eric Blake ebl...@redhat.com
 to the commit message.

Ping.
http://patchwork.ozlabs.org/patch/399483/

BR
Magnus Reftel



Re: [Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-14 Thread Magnus Reftel
On Fri, Oct 10, 2014 at 6:20 PM, Eric Blake ebl...@redhat.com wrote:
 On 10/10/2014 02:16 AM, Magnus Reftel wrote:
 On Thu, Oct 9, 2014 at 11:30 PM, Eric Blake ebl...@redhat.com wrote:
 On 10/09/2014 01:12 PM, Magnus Reftel wrote:
 +if (parse_uint(arg, seed, end, 0) != 0 || *end != 0 || seed  
 UINT_MAX) {

 Slightly shorter as:

 if (parse_uint_full(arg, seed, 0)  0 || seed  UINT_MAX) {

 but that's not a functional difference.

 That would silently truncate and accept strings containing illegal
 characters at the end, e.g. 123a would be treated at 123 (decimal)

 No, the whole point of using parse_uint_full() instead of parse_uint()
 is that parse_uint_full() has one less parameter and enforces no
 trailing garbage on your behalf.

Right, missed the _full. Sending an updated patch.

BR
Magnus Reftel



[Qemu-devel] [PATCH v4] linux-user: Let user specify random seed

2014-10-14 Thread Magnus Reftel
linux-user uses the rand function for generating the value of the AT_RANDOM elf
aux vector entry, and explicitly seeds the random number generator with the
current time. This makes it impossible to reproduce runs that use the AT_RANDOM
bytes.

This patch adds a command line option and a matching environment variable for
setting the random seed, so that the AT_RANDOM values can be predictable when
the user chooses. The default is still to seed the random number generator
with the current time.

This is an updated version of the patch, addressing a review comment from
Eric Blake on version 3.



[Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-14 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

Signed-off-by: Magnus Reftel ref...@spotify.com
---
 linux-user/elfload.c |  1 -
 linux-user/main.c| 19 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1c04fcf..f2e2197 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
  * Generate 16 random bytes for userspace PRNG seeding (not
  * cryptically secure but it's not the aim of QEMU).
  */
-srand((unsigned int) time(NULL));
 for (i = 0; i  16; i++) {
 k_rand_bytes[i] = rand();
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 483eb3f..5887022 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3546,6 +3546,17 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
+static void handle_arg_randseed(const char *arg)
+{
+unsigned long long seed;
+
+if (parse_uint_full(arg, seed, 0) != 0 || seed  UINT_MAX) {
+fprintf(stderr, Invalid seed number: %s\n, arg);
+exit(1);
+}
+srand(seed);
+}
+
 static void handle_arg_gdb(const char *arg)
 {
 gdbstub_port = atoi(arg);
@@ -3674,6 +3685,8 @@ static const struct qemu_argument arg_table[] = {
  ,   run in singlestep mode},
 {strace, QEMU_STRACE,  false, handle_arg_strace,
  ,   log system calls},
+{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
+ ,   Seed for pseudo-random number generator},
 {version,QEMU_VERSION, false, handle_arg_version,
  ,   display version information and exit},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -3856,6 +3869,8 @@ int main(int argc, char **argv, char **envp)
 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 #endif
 
+srand(time(NULL));
+
 optind = parse_args(argc, argv);
 
 /* Zero out regs */
@@ -3926,6 +3941,10 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
+if (getenv(QEMU_RAND_SEED)) {
+handle_arg_randseed(getenv(QEMU_RAND_SEED));
+}
+
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
-- 
1.9.1




[Qemu-devel] [PATCH v5] linux-user: Let user specify random seed

2014-10-14 Thread Magnus Reftel
linux-user uses the rand function for generating the value of the AT_RANDOM elf
aux vector entry, and explicitly seeds the random number generator with the
current time. This makes it impossible to reproduce runs that use the AT_RANDOM
bytes.

This patch adds a command line option and a matching environment variable for
setting the random seed, so that the AT_RANDOM values can be predictable when
the user chooses. The default is still to seed the random number generator
with the current time.

The difference from version 4 of the patch is only the addition of the line
  Reviewed-by: Eric Blake ebl...@redhat.com
to the commit message.



[Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-14 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

Signed-off-by: Magnus Reftel ref...@spotify.com
Reviewed-by: Eric Blake ebl...@redhat.com
---
 linux-user/elfload.c |  1 -
 linux-user/main.c| 19 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1c04fcf..f2e2197 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
  * Generate 16 random bytes for userspace PRNG seeding (not
  * cryptically secure but it's not the aim of QEMU).
  */
-srand((unsigned int) time(NULL));
 for (i = 0; i  16; i++) {
 k_rand_bytes[i] = rand();
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 483eb3f..5887022 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3546,6 +3546,17 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
+static void handle_arg_randseed(const char *arg)
+{
+unsigned long long seed;
+
+if (parse_uint_full(arg, seed, 0) != 0 || seed  UINT_MAX) {
+fprintf(stderr, Invalid seed number: %s\n, arg);
+exit(1);
+}
+srand(seed);
+}
+
 static void handle_arg_gdb(const char *arg)
 {
 gdbstub_port = atoi(arg);
@@ -3674,6 +3685,8 @@ static const struct qemu_argument arg_table[] = {
  ,   run in singlestep mode},
 {strace, QEMU_STRACE,  false, handle_arg_strace,
  ,   log system calls},
+{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
+ ,   Seed for pseudo-random number generator},
 {version,QEMU_VERSION, false, handle_arg_version,
  ,   display version information and exit},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -3856,6 +3869,8 @@ int main(int argc, char **argv, char **envp)
 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 #endif
 
+srand(time(NULL));
+
 optind = parse_args(argc, argv);
 
 /* Zero out regs */
@@ -3926,6 +3941,10 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
+if (getenv(QEMU_RAND_SEED)) {
+handle_arg_randseed(getenv(QEMU_RAND_SEED));
+}
+
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
-- 
1.9.1




Re: [Qemu-devel] [PATCH v2] linux-user: Let user specify random seed

2014-10-10 Thread Magnus Reftel
On Thu, Oct 9, 2014 at 9:43 PM, Tom Musta tommu...@gmail.com wrote:
 On 10/9/2014 3:36 AM, Magnus Reftel wrote:
 This patch introduces the -seed command line option and the
 QEMU_RAND_SEED environment variable for setting the random seed, which
 is used for the AT_RANDOM ELF aux entry.

 This is an updated version of the patch, addressing review comments
 from Eric Blake.
 Possibly a dumb question:  In a regular environment, is there a way for a 
 user to control the 16 bytes of random data
 pointed to by AT_RANDOM?  (I cannot find one).

 If not, why is this capability needed in Linux user mode?

The reason for this feature is to enable fully reproducible automatic
testing. You are correct that this is currently lacking in the Linux
kernel (the random bytes are always obtained using get_random_bytes).
For my purposes, having reproducibility under qemu is enough, but if
I'd be running on bare metal, I'd submit a patch for the kernel as
well.

BR
Magnus Reftel



Re: [Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-10 Thread Magnus Reftel
On Thu, Oct 9, 2014 at 11:30 PM, Eric Blake ebl...@redhat.com wrote:
 On 10/09/2014 01:12 PM, Magnus Reftel wrote:
 +if (parse_uint(arg, seed, end, 0) != 0 || *end != 0 || seed  
 UINT_MAX) {

 Slightly shorter as:

 if (parse_uint_full(arg, seed, 0)  0 || seed  UINT_MAX) {

 but that's not a functional difference.

That would silently truncate and accept strings containing illegal
characters at the end, e.g. 123a would be treated at 123 (decimal)
while it was likely intended to be 0x123a. Therefore, I suggest to
keep the code as proposed in version 3 of the patch.

BR
Magnus



[Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-09 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

Signed-off-by: Magnus Reftel ref...@spotify.com
---
 linux-user/elfload.c |  1 -
 linux-user/main.c| 20 
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1c04fcf..f2e2197 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
  * Generate 16 random bytes for userspace PRNG seeding (not
  * cryptically secure but it's not the aim of QEMU).
  */
-srand((unsigned int) time(NULL));
 for (i = 0; i  16; i++) {
 k_rand_bytes[i] = rand();
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 483eb3f..e80255c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3546,6 +3546,18 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
+static void handle_arg_randseed(const char *arg)
+{
+unsigned long seed;
+char* end;
+seed = strtoul(arg, end, 0);
+if (end==arg || *end!='\0' || seed  UINT_MAX) {
+fprintf(stderr, Invalid seed number: %s\n, arg);
+exit(1);
+}
+srand(seed);
+}
+
 static void handle_arg_gdb(const char *arg)
 {
 gdbstub_port = atoi(arg);
@@ -3674,6 +3686,8 @@ static const struct qemu_argument arg_table[] = {
  ,   run in singlestep mode},
 {strace, QEMU_STRACE,  false, handle_arg_strace,
  ,   log system calls},
+{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
+ ,   Seed for pseudo-random number generator},
 {version,QEMU_VERSION, false, handle_arg_version,
  ,   display version information and exit},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -3856,6 +3870,8 @@ int main(int argc, char **argv, char **envp)
 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 #endif
 
+srand(time(NULL));
+
 optind = parse_args(argc, argv);
 
 /* Zero out regs */
@@ -3926,6 +3942,10 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
+if (getenv(QEMU_RAND_SEED)) {
+handle_arg_randseed(getenv(QEMU_RAND_SEED));
+}
+
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
-- 
1.9.1




[Qemu-devel] [PATCH v2] linux-user: Let user specify random seed

2014-10-09 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

This is an updated version of the patch, addressing review comments
from Eric Blake.



Re: [Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-09 Thread Magnus Reftel
Hi,

Thank you for your patience! I will send a third version.

On Thu, Oct 9, 2014 at 5:27 PM, Eric Blake ebl...@redhat.com wrote:
 On 10/09/2014 02:36 AM, Magnus Reftel wrote:
 +char* end;
 Style: we prefer:
 char *end;

Done.

 +if (end==arg || *end!='\0' || seed  UINT_MAX) {
 Style: spaces around operators:

Done.

 Bug: strtoul() sometimes reports error via errno; the only safe way to
 use it is to first prime errno = 0, then do strtoul, then check if errno
 was changed.

 Reimplementation: util/cutils.c already provides parse_uint() that takes
 care of calling strtoul safely (hmm, that version only parses 64-bit
 numbers; maybe we should expand it to also parse 32-bit numbers?)

Solved both by switching to parse_uint.

 +{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
 + ,   Seed for pseudo-random number generator},
...
 +if (getenv(QEMU_RAND_SEED)) {
 +handle_arg_randseed(getenv(QEMU_RAND_SEED));
 +}

 Now that you have exactly one caller of the static function, it might
 make sense to just inline the body of that function here.

No, it may be called using the function pointer in the argument table, above.

Best Regards
Magnus reftel



[Qemu-devel] [PATCH v3] linux-user: Let user specify random seed

2014-10-09 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.



[Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-09 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

Signed-off-by: Magnus Reftel ref...@spotify.com
---
 linux-user/elfload.c |  1 -
 linux-user/main.c| 20 
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1c04fcf..f2e2197 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
  * Generate 16 random bytes for userspace PRNG seeding (not
  * cryptically secure but it's not the aim of QEMU).
  */
-srand((unsigned int) time(NULL));
 for (i = 0; i  16; i++) {
 k_rand_bytes[i] = rand();
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 483eb3f..56e0e28 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3546,6 +3546,18 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
+static void handle_arg_randseed(const char *arg)
+{
+unsigned long long seed;
+char *end;
+
+if (parse_uint(arg, seed, end, 0) != 0 || *end != 0 || seed  UINT_MAX) {
+fprintf(stderr, Invalid seed number: %s\n, arg);
+exit(1);
+}
+srand(seed);
+}
+
 static void handle_arg_gdb(const char *arg)
 {
 gdbstub_port = atoi(arg);
@@ -3674,6 +3686,8 @@ static const struct qemu_argument arg_table[] = {
  ,   run in singlestep mode},
 {strace, QEMU_STRACE,  false, handle_arg_strace,
  ,   log system calls},
+{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
+ ,   Seed for pseudo-random number generator},
 {version,QEMU_VERSION, false, handle_arg_version,
  ,   display version information and exit},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -3856,6 +3870,8 @@ int main(int argc, char **argv, char **envp)
 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 #endif
 
+srand(time(NULL));
+
 optind = parse_args(argc, argv);
 
 /* Zero out regs */
@@ -3926,6 +3942,10 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
+if (getenv(QEMU_RAND_SEED)) {
+handle_arg_randseed(getenv(QEMU_RAND_SEED));
+}
+
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
-- 
1.9.1




[Qemu-devel] [PATCH] Let user specify random seed for linux-user

2014-10-08 Thread Magnus Reftel
linux-user uses the rand function for generating the value of the AT_RANDOM elf
aux vector entry, and explicitly seeds the random number generator with the
current time. This makes it impossible to reproduce runs that use the AT_RANDOM
bytes.

This patch adds a command line option and a matching environment variable for
setting the random seed, so that the AT_RANDOM values can be predictable when
the user chooses. The default is still to seed the random number generator
with the current time.



[Qemu-devel] [PATCH] linux-user: Let user specify random seed

2014-10-08 Thread Magnus Reftel
This patch introduces the -seed command line option and the
QEMU_RAND_SEED environment variable for setting the random seed, which
is used for the AT_RANDOM ELF aux entry.

Signed-off-by: Magnus Reftel ref...@spotify.com
---
 linux-user/elfload.c |  1 -
 linux-user/main.c| 21 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1c04fcf..f2e2197 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
  * Generate 16 random bytes for userspace PRNG seeding (not
  * cryptically secure but it's not the aim of QEMU).
  */
-srand((unsigned int) time(NULL));
 for (i = 0; i  16; i++) {
 k_rand_bytes[i] = rand();
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 483eb3f..57cd721 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -46,6 +46,8 @@ unsigned long mmap_min_addr;
 #if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
 int have_guest_base;
+static bool have_rand_seed = false;
+static int rand_seed;
 #if (TARGET_LONG_BITS == 32)  (HOST_LONG_BITS == 64)
 /*
  * When running 32-on-64 we should make sure we can fit all of the possible
@@ -3546,6 +3548,12 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
+static void handle_arg_randseed(const char *arg)
+{
+have_rand_seed = true;
+rand_seed = atoi(arg);
+}
+
 static void handle_arg_gdb(const char *arg)
 {
 gdbstub_port = atoi(arg);
@@ -3674,6 +3682,8 @@ static const struct qemu_argument arg_table[] = {
  ,   run in singlestep mode},
 {strace, QEMU_STRACE,  false, handle_arg_strace,
  ,   log system calls},
+{seed,   QEMU_RAND_SEED,   true,  handle_arg_randseed,
+ ,   Seed for pseudo-random number generator},
 {version,QEMU_VERSION, false, handle_arg_version,
  ,   display version information and exit},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -3926,6 +3936,17 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
+if (getenv(QEMU_RAND_SEED)) {
+have_rand_seed = true;
+rand_seed = atoi(getenv(QEMU_RAND_SEED));
+}
+
+if (have_rand_seed) {
+srand(rand_seed);
+} else {
+srand((int)time(NULL));
+}
+
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
-- 
1.9.1