Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-18 Thread Christophe Lyon
On 18 September 2015 at 01:18, Moore, Catherine
 wrote:
>
>
>> -Original Message-
>> From: Jonathan Wakely [mailto:jwak...@redhat.com]
>> Sent: Thursday, September 17, 2015 6:54 PM
>> To: Moore, Catherine; fdum...@gcc.gnu.org
>> Cc: Gerald Pfeifer; libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
>> Subject: Re: [patch] libstdc++/65142 Check read() result in
>> std::random_device.
>>
>> On 17/09/15 22:32 +, Moore, Catherine wrote:
>> >
>> >
>> >> -Original Message-
>> >> From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
>> >> ow...@gcc.gnu.org] On Behalf Of Jonathan Wakely
>> >> Sent: Thursday, September 17, 2015 5:28 PM
>> >> To: Gerald Pfeifer
>> >> Cc: libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
>> >> Subject: Re: [patch] libstdc++/65142 Check read() result in
>> >> std::random_device.
>> >>
>> >> On 17/09/15 22:21 +0200, Gerald Pfeifer wrote:
>> >> >On Thu, 17 Sep 2015, Jonathan Wakely wrote:
>> >> >>> Any comments on this version?
>> >> >> Committed to trunk.
>> >> >
>> >> >Unfortunately this broke bootstrap on FreeBSD 10.1.
>> >> >
>> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In
>> >> member function 'std::random_device::result_type
>> >> std::random_device::_M_getval()':
>> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-
>> v3/src/c++11/random.cc:144:22:
>> >> >error: 'errno' was not declared in this scope
>> >> >  else if (e != -1 || errno != EINTR)
>> >> >  ^
>> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-
>> v3/src/c++11/random.cc:144:31:
>> >> >error: 'EINTR' was not declared in this scope
>> >> >  else if (e != -1 || errno != EINTR)
>> >> >   ^
>> >> >Makefile:545: recipe for target 'random.lo' failed
>> >> >
>> >> >I probably won't be able to dig in deeper today, but figured this
>> >> >might already send you on the right path?
>> >> >
>> >> >Actually...
>> >> >
>> >> >...how about he patch below?  Bootstraps on
>> >> >i386-unknown-freebsd10.1, no regressions.
>> >>
>> >> Sorry about that, I've committed your patch.
>> >>
>> >> >Gerald
>> >> >
>> >> >
>> >I'm still seeing errors for a build of the mips-sde-elf target with these
>> patches.
>> >
>> >Errors are:
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc: In function 'void
>> {anonymous}::print_word({anonymous
>> >}::PrintContext&, const char*, std::ptrdiff_t)':
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:573:10: error: 'stderr' was not declared in this scop
>> >e
>> >  fprintf(stderr, "\n");
>> >  ^
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:573:22: error: 'fprintf' was not declared in this sco
>> >pe
>> >  fprintf(stderr, "\n");
>> >  ^
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:596:14: error: 'stderr' was not declared in this scop e
>> >  fprintf(stderr, "%s", spacing);
>> >  ^
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:596:35: error: 'fprintf' was not declared in this sco pe
>> >  fprintf(stderr, "%s", spacing);
>> >   ^
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:600:24: error: 'stderr' was not declared in this
>> >scope
>> >  int written = fprintf(stderr, "%s", word);
>> >^
>> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
>> >rc/c++11/debug.cc:600:42: error: 'fprintf' was not declared in this
>> >scop e
>> >  int written = fprintf(stderr, "%s", word);
>>
>> That's a different problem, due to https://gcc.gnu.org/r227885
>>
>> François, could you take a look please?
>>
>
> I've now committed this patch to solve this problem (pre-approved by 
> Jonathan).
>
> 2015-09-17  Catherine Moore  
>
> * src/c++11/debug.cc: Include .
>
>
Thanks Catherine, I confirm that it fixes the arm*elf and aarch64*elf
builds too.

Christophe.

> Index: src/c++11/debug.cc
> ===
> --- src/c++11/debug.cc  (revision 227887)
> +++ src/c++11/debug.cc  (working copy)
> @@ -32,6 +32,7 @@
>  #include 
>
>  #include 
> +#include 
>
>  #include  // for std::min
>  #include  // for _Hash_impl


RE: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Moore, Catherine


> -Original Message-
> From: Jonathan Wakely [mailto:jwak...@redhat.com]
> Sent: Thursday, September 17, 2015 6:54 PM
> To: Moore, Catherine; fdum...@gcc.gnu.org
> Cc: Gerald Pfeifer; libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
> Subject: Re: [patch] libstdc++/65142 Check read() result in
> std::random_device.
> 
> On 17/09/15 22:32 +, Moore, Catherine wrote:
> >
> >
> >> -Original Message-
> >> From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
> >> ow...@gcc.gnu.org] On Behalf Of Jonathan Wakely
> >> Sent: Thursday, September 17, 2015 5:28 PM
> >> To: Gerald Pfeifer
> >> Cc: libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
> >> Subject: Re: [patch] libstdc++/65142 Check read() result in
> >> std::random_device.
> >>
> >> On 17/09/15 22:21 +0200, Gerald Pfeifer wrote:
> >> >On Thu, 17 Sep 2015, Jonathan Wakely wrote:
> >> >>> Any comments on this version?
> >> >> Committed to trunk.
> >> >
> >> >Unfortunately this broke bootstrap on FreeBSD 10.1.
> >> >
> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In
> >> member function 'std::random_device::result_type
> >> std::random_device::_M_getval()':
> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-
> v3/src/c++11/random.cc:144:22:
> >> >error: 'errno' was not declared in this scope
> >> >  else if (e != -1 || errno != EINTR)
> >> >  ^
> >> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-
> v3/src/c++11/random.cc:144:31:
> >> >error: 'EINTR' was not declared in this scope
> >> >  else if (e != -1 || errno != EINTR)
> >> >   ^
> >> >Makefile:545: recipe for target 'random.lo' failed
> >> >
> >> >I probably won't be able to dig in deeper today, but figured this
> >> >might already send you on the right path?
> >> >
> >> >Actually...
> >> >
> >> >...how about he patch below?  Bootstraps on
> >> >i386-unknown-freebsd10.1, no regressions.
> >>
> >> Sorry about that, I've committed your patch.
> >>
> >> >Gerald
> >> >
> >> >
> >I'm still seeing errors for a build of the mips-sde-elf target with these
> patches.
> >
> >Errors are:
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc: In function 'void
> {anonymous}::print_word({anonymous
> >}::PrintContext&, const char*, std::ptrdiff_t)':
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:573:10: error: 'stderr' was not declared in this scop
> >e
> >  fprintf(stderr, "\n");
> >  ^
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:573:22: error: 'fprintf' was not declared in this sco
> >pe
> >  fprintf(stderr, "\n");
> >  ^
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:596:14: error: 'stderr' was not declared in this scop e
> >  fprintf(stderr, "%s", spacing);
> >  ^
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:596:35: error: 'fprintf' was not declared in this sco pe
> >  fprintf(stderr, "%s", spacing);
> >   ^
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:600:24: error: 'stderr' was not declared in this
> >scope
> >  int written = fprintf(stderr, "%s", word);
> >^
> >/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/s
> >rc/c++11/debug.cc:600:42: error: 'fprintf' was not declared in this
> >scop e
> >  int written = fprintf(stderr, "%s", word);
> 
> That's a different problem, due to https://gcc.gnu.org/r227885
> 
> François, could you take a look please?
> 

I've now committed this patch to solve this problem (pre-approved by Jonathan).

2015-09-17  Catherine Moore  

* src/c++11/debug.cc: Include .


Index: src/c++11/debug.cc
===
--- src/c++11/debug.cc  (revision 227887)
+++ src/c++11/debug.cc  (working copy)
@@ -32,6 +32,7 @@
 #include 

 #include 
+#include 

 #include  // for std::min
 #include  // for _Hash_impl


Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Jonathan Wakely

On 17/09/15 22:32 +, Moore, Catherine wrote:




-Original Message-
From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
ow...@gcc.gnu.org] On Behalf Of Jonathan Wakely
Sent: Thursday, September 17, 2015 5:28 PM
To: Gerald Pfeifer
Cc: libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
Subject: Re: [patch] libstdc++/65142 Check read() result in
std::random_device.

On 17/09/15 22:21 +0200, Gerald Pfeifer wrote:
>On Thu, 17 Sep 2015, Jonathan Wakely wrote:
>>> Any comments on this version?
>> Committed to trunk.
>
>Unfortunately this broke bootstrap on FreeBSD 10.1.
>
>/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In
member function 'std::random_device::result_type
std::random_device::_M_getval()':
>/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:22:
>error: 'errno' was not declared in this scope
>  else if (e != -1 || errno != EINTR)
>  ^
>/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:31:
>error: 'EINTR' was not declared in this scope
>  else if (e != -1 || errno != EINTR)
>   ^
>Makefile:545: recipe for target 'random.lo' failed
>
>I probably won't be able to dig in deeper today, but figured this might
>already send you on the right path?
>
>Actually...
>
>...how about he patch below?  Bootstraps on i386-unknown-freebsd10.1,
>no regressions.

Sorry about that, I've committed your patch.

>Gerald
>
>

I'm still seeing errors for a build of the mips-sde-elf target with these 
patches.

Errors are:
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:
 In function 'void {anonymous}::print_word({anonymous
}::PrintContext&, const char*, std::ptrdiff_t)':
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:573:10:
 error: 'stderr' was not declared in this scop
e
 fprintf(stderr, "\n");
 ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:573:22:
 error: 'fprintf' was not declared in this sco
pe
 fprintf(stderr, "\n");
 ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:596:14:
 error: 'stderr' was not declared in this scop
e
 fprintf(stderr, "%s", spacing);
 ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:596:35:
 error: 'fprintf' was not declared in this sco
pe
 fprintf(stderr, "%s", spacing);
  ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:600:24:
 error: 'stderr' was not declared in this scope
 int written = fprintf(stderr, "%s", word);
   ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:600:42:
 error: 'fprintf' was not declared in this scop
e
 int written = fprintf(stderr, "%s", word);


That's a different problem, due to https://gcc.gnu.org/r227885

François, could you take a look please?




RE: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Moore, Catherine


> -Original Message-
> From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
> ow...@gcc.gnu.org] On Behalf Of Jonathan Wakely
> Sent: Thursday, September 17, 2015 5:28 PM
> To: Gerald Pfeifer
> Cc: libstd...@gcc.gnu.org; gcc-patches@gcc.gnu.org
> Subject: Re: [patch] libstdc++/65142 Check read() result in
> std::random_device.
> 
> On 17/09/15 22:21 +0200, Gerald Pfeifer wrote:
> >On Thu, 17 Sep 2015, Jonathan Wakely wrote:
> >>> Any comments on this version?
> >> Committed to trunk.
> >
> >Unfortunately this broke bootstrap on FreeBSD 10.1.
> >
> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In
> member function 'std::random_device::result_type
> std::random_device::_M_getval()':
> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:22:
> >error: 'errno' was not declared in this scope
> >  else if (e != -1 || errno != EINTR)
> >  ^
> >/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:31:
> >error: 'EINTR' was not declared in this scope
> >  else if (e != -1 || errno != EINTR)
> >   ^
> >Makefile:545: recipe for target 'random.lo' failed
> >
> >I probably won't be able to dig in deeper today, but figured this might
> >already send you on the right path?
> >
> >Actually...
> >
> >...how about he patch below?  Bootstraps on i386-unknown-freebsd10.1,
> >no regressions.
> 
> Sorry about that, I've committed your patch.
> 
> >Gerald
> >
> >
I'm still seeing errors for a build of the mips-sde-elf target with these 
patches.

Errors are:
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:
 In function 'void {anonymous}::print_word({anonymous
}::PrintContext&, const char*, std::ptrdiff_t)':
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:573:10:
 error: 'stderr' was not declared in this scop
e
  fprintf(stderr, "\n");
  ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:573:22:
 error: 'fprintf' was not declared in this sco
pe
  fprintf(stderr, "\n");
  ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:596:14:
 error: 'stderr' was not declared in this scop
e
  fprintf(stderr, "%s", spacing);
  ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:596:35:
 error: 'fprintf' was not declared in this sco
pe
  fprintf(stderr, "%s", spacing);
   ^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:600:24:
 error: 'stderr' was not declared in this scope
  int written = fprintf(stderr, "%s", word);
^
/scratch/cmoore/virgin-upstream-elf-lite/src/gcc-trunk-5/libstdc++-v3/src/c++11/debug.cc:600:42:
 error: 'fprintf' was not declared in this scop
e
  int written = fprintf(stderr, "%s", word);
  ^

Thanks,
Catherine



Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Jonathan Wakely

On 17/09/15 22:21 +0200, Gerald Pfeifer wrote:

On Thu, 17 Sep 2015, Jonathan Wakely wrote:

Any comments on this version?

Committed to trunk.


Unfortunately this broke bootstrap on FreeBSD 10.1.

/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In member 
function 'std::random_device::result_type std::random_device::_M_getval()':
/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:22: error: 
'errno' was not declared in this scope
 else if (e != -1 || errno != EINTR)
 ^
/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:31: error: 
'EINTR' was not declared in this scope
 else if (e != -1 || errno != EINTR)
  ^
Makefile:545: recipe for target 'random.lo' failed

I probably won't be able to dig in deeper today, but figured this
might already send you on the right path?

Actually...

...how about he patch below?  Bootstraps on i386-unknown-freebsd10.1,
no regressions.


Sorry about that, I've committed your patch.


Gerald


2015-09-17  Gerald Pfeifer  

* src/c++11/random.cc: Include .

Index: libstdc++-v3/src/c++11/random.cc
===
--- libstdc++-v3/src/c++11/random.cc(revision 227883)
+++ libstdc++-v3/src/c++11/random.cc(working copy)
@@ -31,6 +31,7 @@
# include 
#endif

+#include 
#include 

#ifdef _GLIBCXX_HAVE_UNISTD_H


Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Gerald Pfeifer
On Thu, 17 Sep 2015, Jonathan Wakely wrote:
>> Any comments on this version?
> Committed to trunk.

Unfortunately this broke bootstrap on FreeBSD 10.1.

/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc: In member 
function 'std::random_device::result_type std::random_device::_M_getval()':
/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:22: error: 
'errno' was not declared in this scope
  else if (e != -1 || errno != EINTR)
  ^
/scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/random.cc:144:31: error: 
'EINTR' was not declared in this scope
  else if (e != -1 || errno != EINTR)
   ^
Makefile:545: recipe for target 'random.lo' failed

I probably won't be able to dig in deeper today, but figured this
might already send you on the right path?

Actually...

...how about he patch below?  Bootstraps on i386-unknown-freebsd10.1,
no regressions.

Gerald


2015-09-17  Gerald Pfeifer  

* src/c++11/random.cc: Include .

Index: libstdc++-v3/src/c++11/random.cc
===
--- libstdc++-v3/src/c++11/random.cc(revision 227883)
+++ libstdc++-v3/src/c++11/random.cc(working copy)
@@ -31,6 +31,7 @@
 # include 
 #endif
 
+#include 
 #include 
 
 #ifdef _GLIBCXX_HAVE_UNISTD_H


Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-17 Thread Jonathan Wakely

On 15/09/15 12:47 +0100, Jonathan Wakely wrote:

On 11/09/15 14:44 +0100, Jonathan Wakely wrote:

We should not silently ignore a failure to read from the random
device.

Tested powerpc64le-linux, committed to trunk. I'm going to commit this
to the gcc-5 branch too.





commit 2d2f7012dc3744dafef0de94dd845bd190253dbd
Author: Jonathan Wakely 
Date:   Fri Feb 20 17:29:50 2015 +

  Check read() result in std::random_device.
PR libstdc++/65142
* src/c++11/random.cc (random_device::_M_getval()): Check read result.

diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index edf900f..1d102c7 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,13 +130,17 @@ namespace std _GLIBCXX_VISIBILITY(default)
#endif

   result_type __ret;
+
#ifdef _GLIBCXX_HAVE_UNISTD_H
-read(fileno(static_cast(_M_file)),
-static_cast(&__ret), sizeof(result_type));
+auto e = read(fileno(static_cast(_M_file)),
+ static_cast(&__ret), sizeof(result_type));
#else
-std::fread(static_cast(&__ret), sizeof(result_type),
-  1, static_cast(_M_file));
+auto e = std::fread(static_cast(&__ret), sizeof(result_type),
+   1, static_cast(_M_file));
#endif
+if (e != sizeof(result_type))
+  __throw_runtime_error(__N("random_device could not read enough bytes"));
+
   return __ret;
 }



Florian pointed out that this code should handle short reads (or
EINTR) by retrying in a loop, so here's another attempt to fix it.

This also fixes the bug I introduced in the std::fread() case where it
expects e == sizeof(result_type) but fread will only return 0 or 1.

We could loop in the fread case too, but I'm not doing that. If
someone on non-POSIX targets cares enough they can make that change
later.

Any comments on this version?


Committed to trunk.



commit 6700c8c652da94332562fff465a1569d8fa9c94d
Author: Jonathan Wakely 
Date:   Tue Sep 15 11:02:42 2015 +0100

   Fix handling of short reads in std::random_device
   
   	PR libstdc++/65142

* src/c++11/random.cc (random_device::_M_getval()): Retry after short
reads.

diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 1d102c7..f1d6125 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,16 +130,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
#endif

result_type __ret;
-
+void* p = &__ret;
+size_t n = sizeof(result_type);
#ifdef _GLIBCXX_HAVE_UNISTD_H
-auto e = read(fileno(static_cast(_M_file)),
- static_cast(&__ret), sizeof(result_type));
+do
+  {
+   const int e = read(fileno(static_cast(_M_file)), p, n);
+   if (e > 0)
+ {
+   n -= e;
+   p = static_cast(p) + e;
+ }
+   else if (e != -1 || errno != EINTR)
+ __throw_runtime_error(__N("random_device could not be read"));
+  }
+while (n > 0);
#else
-auto e = std::fread(static_cast(&__ret), sizeof(result_type),
-   1, static_cast(_M_file));
+const size_t e = std::fread(p, n, 1, static_cast(_M_file));
+if (e != 1)
+  __throw_runtime_error(__N("random_device could not be read"));
#endif
-if (e != sizeof(result_type))
-  __throw_runtime_error(__N("random_device could not read enough bytes"));

return __ret;
  }




Re: [patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-15 Thread Jonathan Wakely

On 11/09/15 14:44 +0100, Jonathan Wakely wrote:

We should not silently ignore a failure to read from the random
device.

Tested powerpc64le-linux, committed to trunk. I'm going to commit this
to the gcc-5 branch too.





commit 2d2f7012dc3744dafef0de94dd845bd190253dbd
Author: Jonathan Wakely 
Date:   Fri Feb 20 17:29:50 2015 +

   Check read() result in std::random_device.
   
   	PR libstdc++/65142

* src/c++11/random.cc (random_device::_M_getval()): Check read result.

diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index edf900f..1d102c7 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,13 +130,17 @@ namespace std _GLIBCXX_VISIBILITY(default)
#endif

result_type __ret;
+
#ifdef _GLIBCXX_HAVE_UNISTD_H
-read(fileno(static_cast(_M_file)),
-static_cast(&__ret), sizeof(result_type));
+auto e = read(fileno(static_cast(_M_file)),
+ static_cast(&__ret), sizeof(result_type));
#else
-std::fread(static_cast(&__ret), sizeof(result_type),
-  1, static_cast(_M_file));
+auto e = std::fread(static_cast(&__ret), sizeof(result_type),
+   1, static_cast(_M_file));
#endif
+if (e != sizeof(result_type))
+  __throw_runtime_error(__N("random_device could not read enough bytes"));
+
return __ret;
  }



Florian pointed out that this code should handle short reads (or
EINTR) by retrying in a loop, so here's another attempt to fix it.

This also fixes the bug I introduced in the std::fread() case where it
expects e == sizeof(result_type) but fread will only return 0 or 1.

We could loop in the fread case too, but I'm not doing that. If
someone on non-POSIX targets cares enough they can make that change
later.

Any comments on this version?

commit 6700c8c652da94332562fff465a1569d8fa9c94d
Author: Jonathan Wakely 
Date:   Tue Sep 15 11:02:42 2015 +0100

Fix handling of short reads in std::random_device

	PR libstdc++/65142
	* src/c++11/random.cc (random_device::_M_getval()): Retry after short
	reads.

diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 1d102c7..f1d6125 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,16 +130,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
 
 result_type __ret;
-
+void* p = &__ret;
+size_t n = sizeof(result_type);
 #ifdef _GLIBCXX_HAVE_UNISTD_H
-auto e = read(fileno(static_cast(_M_file)),
-		  static_cast(&__ret), sizeof(result_type));
+do
+  {
+	const int e = read(fileno(static_cast(_M_file)), p, n);
+	if (e > 0)
+	  {
+	n -= e;
+	p = static_cast(p) + e;
+	  }
+	else if (e != -1 || errno != EINTR)
+	  __throw_runtime_error(__N("random_device could not be read"));
+  }
+while (n > 0);
 #else
-auto e = std::fread(static_cast(&__ret), sizeof(result_type),
-		1, static_cast(_M_file));
+const size_t e = std::fread(p, n, 1, static_cast(_M_file));
+if (e != 1)
+  __throw_runtime_error(__N("random_device could not be read"));
 #endif
-if (e != sizeof(result_type))
-  __throw_runtime_error(__N("random_device could not read enough bytes"));
 
 return __ret;
   }


[patch] libstdc++/65142 Check read() result in std::random_device.

2015-09-11 Thread Jonathan Wakely

We should not silently ignore a failure to read from the random
device.

Tested powerpc64le-linux, committed to trunk. I'm going to commit this
to the gcc-5 branch too.


commit 2d2f7012dc3744dafef0de94dd845bd190253dbd
Author: Jonathan Wakely 
Date:   Fri Feb 20 17:29:50 2015 +

Check read() result in std::random_device.

	PR libstdc++/65142
	* src/c++11/random.cc (random_device::_M_getval()): Check read result.

diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index edf900f..1d102c7 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -130,13 +130,17 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
 
 result_type __ret;
+
 #ifdef _GLIBCXX_HAVE_UNISTD_H
-read(fileno(static_cast(_M_file)),
-	 static_cast(&__ret), sizeof(result_type));
+auto e = read(fileno(static_cast(_M_file)),
+		  static_cast(&__ret), sizeof(result_type));
 #else
-std::fread(static_cast(&__ret), sizeof(result_type),
-	   1, static_cast(_M_file));
+auto e = std::fread(static_cast(&__ret), sizeof(result_type),
+		1, static_cast(_M_file));
 #endif
+if (e != sizeof(result_type))
+  __throw_runtime_error(__N("random_device could not read enough bytes"));
+
 return __ret;
   }