Re: [patch] libstdc++/65142 Check read() result in std::random_device.
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.
> -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.
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.
> -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.
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.
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.
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.
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; }