lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <54707352.8050208@gmx.de>
Date:	Sat, 22 Nov 2014 12:28:18 +0100
From:	Heinrich Schuchardt <xypron.glpk@....de>
To:	Theodore Ts'o <tytso@....edu>
CC:	Michael Kerrisk <mtk.manpages@...il.com>,
	linux-man <linux-man@...r.kernel.org>,
	lkml <linux-kernel@...r.kernel.org>
Subject: getrandom.2: treatment of interrupts

Hello Theodore,

I created the test program below.

While running it I issued
kill -SIGUSR1 <pid>
and
kill -SIGUSR2 <pid>

What I found was rather strange.

No matter whether specifying GRND_NONBLOCK or not, signals do not 
interrupt the execution of getrandom() while reading from the 
/dev/urandom pool.

Only after getrandom has finished signals are handled.

I would have expected getrandom() to react to interrupts immediately and 
to return whatever number of random bytes have been collected before the 
interrupt.

A system call not reacting to interrupts for several seconds looks like 
a bug to me.

Tested on Linux 3.18.0-rc4 mips64.

Best regards

Heinrich Schuchardt



#define _GNU_SOURCE
#include <errno.h>
#include <linux/unistd.h>
#include <linux/random.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.h>

#if _MIPS_SIM == _MIPS_SIM_ABI32
#define __NR_getrandom                  (__NR_Linux + 353)
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */

#if _MIPS_SIM == _MIPS_SIM_ABI64
#define __NR_getrandom                  (__NR_Linux + 313)
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */

#if _MIPS_SIM == _MIPS_SIM_NABI32
#define __NR_getrandom                  (__NR_Linux + 317)
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */

#ifdef __i386__
#define __NR_getrandom                  (355)
#endif /* __i386__ */

#ifdef __x86_64__
#define __NR_getrandom                  (318)
#endif /* __x86_64__ */

#define SYS_getrandom __NR_getrandom

#define GRND_NONBLOCK   0x0001
#define GRND_RANDOM     0x0002

#define BUFLEN 0x12345678

int getrandom(void *buf, size_t buflen, unsigned int flags)
{
         return syscall(SYS_getrandom, buf, buflen, flags);
}

/**
  * Handles signal.
  *
  * @param sig signal
  */


int do_print = 0;

static void hdl(int sig)
{
         if (sig == SIGUSR1) {
                 fprintf(stderr, "Main received SIGUSR1\n");
                 do_print = 1;
         }
}

int
main(int argc, char *argv[])
{

         char *buf;
         size_t buflen = BUFLEN;
         int ret;
         pid_t pid;
         // action to take when signal occurs
         struct sigaction act;
         // signal mask
         sigset_t blockset;


         pid = getpid();

         printf("PID = %u\n", pid);

         printf("__NR_getrandom = %u\n", __NR_getrandom);

         // Set handler for SIGUSR1
         act.sa_handler = hdl;
         sigemptyset(&act.sa_mask);
         act.sa_flags = 0;
         if (sigaction(SIGUSR1, &act, NULL)) {
                 perror("sigaction");
                 exit(EXIT_FAILURE);
         }

         buf = (char *) malloc(buflen);
         if (buf == NULL) {
                 perror("malloc");
                 exit(EXIT_FAILURE);
         }

         buf = (char *) malloc(buflen);

         for (;;) {
                 ret = getrandom(buf, buflen, GRND_NONBLOCK);
                 if (ret == -1) {
                         fprintf(stderr, "errno = %d\n", errno);
                         perror("getrandom");
                         exit(EXIT_FAILURE);
                 }
                 if (do_print) {
                         do_print = 0;
                         printf("ret = %d\n", ret);
                 }

         }
         printf("ret = %d\n", ret);

         free(buf);

         return EXIT_SUCCESS;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ