Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2016-12-14 00:59:31 +0300
committerCorinna Vinschen <corinna@vinschen.de>2016-12-14 00:59:31 +0300
commit74f7872f89dc8ecad500c5d5c4e03b4757f6418d (patch)
tree7b9f8a573c50009c9ad42a653fec8fac94557e1b
parent80f4987f02e50721e4cc62f6d70bc602324d32ad (diff)
Rearrange RNG code slightly
In preparation of exporting getentropy/getrandom to userspace, rearrange code a bit: - Define RtlGenRandom in ntdll.h. - Drop calls to getentropy in favor of RtlGenRandom (fhandler_socket, fhandler_dev_random). - Add try/except blocks in fhandler_dev_random to return EFAULT rather than crashing if buffer pointer is invalid. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/fhandler_random.cc72
-rw-r--r--winsup/cygwin/fhandler_socket.cc2
-rw-r--r--winsup/cygwin/miscfuncs.cc6
-rw-r--r--winsup/cygwin/ntdll.h6
4 files changed, 52 insertions, 34 deletions
diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc
index af76a6614..c56ce73d3 100644
--- a/winsup/cygwin/fhandler_random.cc
+++ b/winsup/cygwin/fhandler_random.cc
@@ -47,16 +47,26 @@ fhandler_dev_random::write (const void *ptr, size_t len)
}
/* Limit len to a value <= 4096 since we don't want to overact.
- Copy to local buffer because CryptGenRandom violates const. */
+ Copy to local buffer because RtlGenRandom violates const. */
size_t limited_len = MIN (len, 4096);
unsigned char buf[limited_len];
- memcpy (buf, ptr, limited_len);
/* Mess up system entropy source. Return error if device is /dev/random. */
- if (getentropy (buf, limited_len) && dev () == FH_RANDOM)
- return -1;
- /* Mess up the pseudo random number generator. */
- pseudo_write (buf, limited_len);
+ __try
+ {
+ memcpy (buf, ptr, limited_len);
+ if (!RtlGenRandom (buf, limited_len) && dev () == FH_RANDOM)
+ return -1;
+ /* Mess up the pseudo random number generator. */
+ pseudo_write (buf, limited_len);
+ }
+ __except (EFAULT)
+ {
+ len = -1;
+ }
+ __endtry
+ /* Note that we return len, not limited_len. No reason to confuse the
+ caller... */
return len;
}
@@ -88,32 +98,40 @@ fhandler_dev_random::read (void *ptr, size_t& len)
return;
}
- /* /dev/random has to provide high quality random numbers. Therefore we
- re-seed the system PRNG for each block of 512 bytes. This results in
- sufficiently random sequences, comparable to the Linux /dev/random. */
- if (dev () == FH_RANDOM)
+ __try
{
- void *dummy = malloc (RESEED_INTERVAL);
- if (!dummy)
+ /* /dev/random has to provide high quality random numbers. Therefore we
+ re-seed the system PRNG for each block of 512 bytes. This results in
+ sufficiently random sequences, comparable to the Linux /dev/random. */
+ if (dev () == FH_RANDOM)
{
- __seterrno ();
- len = (size_t) -1;
- return;
- }
- for (size_t offset = 0; offset < len; offset += 512)
- {
- if (getentropy (dummy, RESEED_INTERVAL) ||
- getentropy ((PBYTE) ptr + offset, len - offset))
+ void *dummy = malloc (RESEED_INTERVAL);
+ if (!dummy)
{
+ __seterrno ();
len = (size_t) -1;
- break;
+ return;
}
+ for (size_t offset = 0; offset < len; offset += 512)
+ {
+ if (!RtlGenRandom (dummy, RESEED_INTERVAL) ||
+ !RtlGenRandom ((PBYTE) ptr + offset, len - offset))
+ {
+ len = (size_t) -1;
+ break;
+ }
+ }
+ free (dummy);
}
- free (dummy);
- }
- /* If device is /dev/urandom, just use system RNG as is, with our own
- PRNG as fallback. */
- else if (getentropy (ptr, len))
- len = pseudo_read (ptr, len);
+ /* If device is /dev/urandom, just use system RNG as is, with our own
+ PRNG as fallback. */
+ else if (!RtlGenRandom (ptr, len))
+ len = pseudo_read (ptr, len);
+ }
+ __except (EFAULT)
+ {
+ len = (size_t) -1;
+ }
+ __endtry
}
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 9ada4697d..801a731a5 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -485,7 +485,7 @@ fhandler_socket::af_local_copy (fhandler_socket *sock)
void
fhandler_socket::af_local_set_secret (char *buf)
{
- if (getentropy (connect_secret, sizeof (connect_secret)))
+ if (!RtlGenRandom (connect_secret, sizeof (connect_secret)))
bzero ((char*) connect_secret, sizeof (connect_secret));
__small_sprintf (buf, "%08x-%08x-%08x-%08x",
connect_secret [0], connect_secret [1],
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index f90d6efa2..0b19b2892 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -233,12 +233,6 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
return -1;
}
-/* There's a bug in ntsecapi.h (Mingw as well as MSFT). SystemFunction036
- is, in fact, a WINAPI function, but it's not defined as such. Therefore
- we have to do it correctly here. */
-#define RtlGenRandom SystemFunction036
-extern "C" BOOLEAN WINAPI RtlGenRandom (PVOID, ULONG);
-
/* Used by arc2random, fhandler_socket and fhandler_random. */
extern "C" int
getentropy (void *ptr, size_t len)
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 448eadf20..bf5a7cf80 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -1608,4 +1608,10 @@ extern "C"
}
}
+
+/* There's a bug in ntsecapi.h (Mingw as well as MSFT). SystemFunction036
+ is, in fact, a WINAPI function, but it's not defined as such. Therefore
+ we have to do it correctly here. *Strictly*, this is not ntdll... */
+#define RtlGenRandom SystemFunction036
+extern "C" BOOLEAN WINAPI RtlGenRandom (PVOID, ULONG);
#endif