Package: apg Version: 2.2.3-3 Severity: important Tags: patch A couple of invocations of apg with certain parameters (apg -M SNCL -m 10 -x 10 -a 1 for example) totally drain /dev/random (from an strace log):
open("/dev/random", O_RDONLY) = 3 [...] read(3, "[\354x\341\375\25\306\337O\322v\243{$m\371WQ\266\210\34"..., 4096) = 128 close(3) = 0 As you can see, apg requests 4096 bytes from /dev/random which is totally excessive since it only uses 8 of them. Now, the code actually requests 8, so the problem is likely in the C library. Attached is a patch to use regular functions open/read/close instead of the C library ones and really read only 8 bytes. -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: powerpc (ppc) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.13-rc3 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages apg depends on: ii libc6 2.3.5-1 GNU C Library: Shared libraries an apg recommends no packages. -- no debconf information
--- apg-2.2.3.orig/rnd.c +++ apg-2.2.3/rnd.c @@ -36,6 +36,7 @@ #include <unistd.h> #include <sys/types.h> #include <sys/time.h> +#include <fcntl.h> #include "rnd.h" #ifndef APG_USE_SHA @@ -176,25 +177,31 @@ void x917_setseed (UINT32 seed, int quiet) { - FILE * dr; + int fd; UINT32 drs[2]; UINT32 pid = 0; pid = (UINT32)getpid(); + + /* NOTE: this function intentionally does not use + * the regular <stdio> API because fread may + * read much more data than requested (up to + * 4K), which is extremely bad with /dev/random + */ - if ( (dr = fopen(APG_DEVRANDOM, "r")) != NULL) + if ( (fd = open(APG_DEVRANDOM, O_RDONLY)) != -1) { - (void)fread( (void *)&drs[0], 8, 1, dr); + read(fd, (void *)&drs[0], 8); __rnd_seed[0] = seed ^ drs[0]; __rnd_seed[1] = seed ^ drs[1]; - (void) fclose(dr); + close(fd); } - else if ( (dr = fopen(APG_DEVURANDOM, "r")) != NULL) + else if ( (fd = open(APG_DEVURANDOM, O_RDONLY)) != -1) { - (void)fread( (void *)&drs[0], 8, 1, dr); + read(fd, &drs[0], 8); __rnd_seed[0] = seed ^ drs[0]; __rnd_seed[1] = seed ^ drs[1]; - (void) fclose(dr); + close(fd); } else {
signature.asc
Description: This is a digitally signed message part