summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-26 13:37:43 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-26 15:19:25 +0200
commit972bf4d69187fa940e039180fc4bdb7eaeee4f62 (patch)
treefdbf90113b47bd8adda2236d04c19f1e8d8b26a7
parent6953f021907ee9bc95380d576debbc653436b96a (diff)
downloadgnutls-getrandom-fix.tar.gz
tests: added unit test for linux _rnd_get_system_entropygetrandom-fix
This tests whether the function can operate as expected while being interrupted by signals.
-rw-r--r--configure.ac2
-rw-r--r--lib/nettle/rnd-linux.c16
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/rng-sigint.c107
4 files changed, 116 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac
index eb752500b2..c31b102b18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -226,7 +226,7 @@ AC_C_BIGENDIAN
dnl No fork on MinGW, disable some self-tests until we fix them.
dnl Check clock_gettime and pthread_mutex_lock in libc (avoid linking to other libs)
-AC_CHECK_FUNCS([fork inet_ntop inet_pton getrusage getpwuid_r nanosleep daemon getpid clock_gettime iconv localtime fmemopen vasprintf mmap],,)
+AC_CHECK_FUNCS([fork setitimer inet_ntop inet_pton getrusage getpwuid_r nanosleep daemon getpid clock_gettime iconv localtime fmemopen vasprintf mmap],,)
if test "$ac_cv_func_vasprintf" != "yes";then
AC_MSG_CHECKING([for va_copy])
AC_LINK_IFELSE([AC_LANG_PROGRAM([
diff --git a/lib/nettle/rnd-linux.c b/lib/nettle/rnd-linux.c
index 3ad9056cb3..a0a86d7826 100644
--- a/lib/nettle/rnd-linux.c
+++ b/lib/nettle/rnd-linux.c
@@ -25,14 +25,13 @@
* getrandom() -> /dev/urandom, where "->" indicates fallback.
*/
-#include "gnutls_int.h"
-#include "errors.h"
-#include <locks.h>
-#include <num.h>
-#include <nettle/yarrow.h>
-#include <errno.h>
-#include <rnd-common.h>
-#include <hash-pjw-bare.h>
+#ifndef RND_NO_INCLUDES
+# include "gnutls_int.h"
+# include "errors.h"
+# include <num.h>
+# include <errno.h>
+# include <rnd-common.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -46,7 +45,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
-#include <locks.h>
static int _gnutls_urandom_fd = -1;
static ino_t _gnutls_urandom_fd_ino = 0;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b92b40bfce..0c0e08c9b8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -111,7 +111,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \
dtls1.2-cert-key-exchange dtls1.0-cert-key-exchange x509-cert-callback-legacy \
keylog-env ssl2-hello tlsfeature-ext dtls-rehandshake-cert-2 \
tlsfeature-crt dtls-rehandshake-cert-3 resume-with-false-start \
- set_x509_key_file_ocsp client-fastopen
+ set_x509_key_file_ocsp client-fastopen rng-sigint
if HAVE_SECCOMP_TESTS
ctests += dtls-with-seccomp tls-with-seccomp dtls-client-with-seccomp tls-client-with-seccomp
diff --git a/tests/rng-sigint.c b/tests/rng-sigint.c
new file mode 100644
index 0000000000..7bf1feea0c
--- /dev/null
+++ b/tests/rng-sigint.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* This program verifies whether the low-level random functions can operate
+ * properly, even if interrupted by signals */
+
+#if defined(HAVE_SETITIMER) && (defined(HAVE_LINUX_GETRANDOM) || defined(__linux__))
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <stdint.h>
+#include "utils.h"
+
+#define _gnutls_debug_log printf
+#define gnutls_assert()
+#define gnutls_assert_val(val) val
+
+int _rnd_system_entropy_init(void);
+int _rnd_system_entropy_check(void);
+void _rnd_system_entropy_deinit(void);
+
+typedef int (*get_entropy_func)(void* rnd, size_t size);
+get_entropy_func _rnd_get_system_entropy;
+
+#define RND_NO_INCLUDES
+#include "../lib/nettle/rnd-linux.c"
+
+static volatile int stop_loop = 0;
+
+static void sig_handler(int signo)
+{
+ stop_loop++;
+}
+
+void doit(void)
+{
+ char buf[512];
+ char empty[32];
+ int ret;
+ struct itimerval ival;
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sig_handler;
+ sigemptyset (&sa.sa_mask);
+ sigaction(SIGALRM, &sa, NULL);
+
+ memset(&ival, 0, sizeof(ival));
+ ival.it_interval.tv_usec = 5000;
+ ival.it_value.tv_usec = 5000;
+
+ _rnd_system_entropy_init();
+
+ ret = setitimer(ITIMER_REAL, &ival, NULL);
+ if (ret < 0) {
+ fail("error in setitimer: %s\n", strerror(errno));
+ }
+
+ memset(empty, 0, sizeof(empty));
+ for (;stop_loop<1024;) {
+ memset(buf, 0, sizeof(buf));
+ ret = _rnd_get_system_entropy(buf, sizeof(buf));
+ if (ret < 0) {
+ fail("error obtaining entropy: %s\n", gnutls_strerror(ret));
+ }
+
+ if (memcmp(empty, buf+sizeof(buf)-sizeof(empty)-1, sizeof(empty)) == 0) {
+ fail("_rnd_get_system_entropy: did not fill buffer\n");
+ }
+ }
+
+ _rnd_system_entropy_deinit();
+}
+#else
+void doit(void)
+{
+ exit(77);
+}
+
+#endif