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
   {

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to