From b1abc01d4ad199258b3d2fb579ac06c6fea747fd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Nov 2012 18:06:27 +0100 Subject: [PATCH] Improve handling of random_seed read errors. * cipher/random.c (read_seed_file): Distinguish between errors and short reads. -- This should help to avoid program aborts due to races. Nevertheless a better and cross-platform locking would be a more solid solution. GnuPG-bug-id: 1439 --- cipher/random.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cipher/random.c b/cipher/random.c index caf35ddf1..b63416134 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -489,14 +489,38 @@ read_seed_file(void) close(fd); return 0; } + do { n = read( fd, buffer, POOLSIZE ); } while( n == -1 && errno == EINTR ); - if( n != POOLSIZE ) { + /* The N==0, ENOENT, and N!=POOLSIZE cases may happen if another + process is updating the file. For consistency we use the same + recovery strategy as with the pre-read checks. */ + if (!n) { + log_info(_("note: random_seed file is empty\n") ); + allow_seed_file_update = 1; + close(fd); + return 0; + } + else if( n == -1 && errno == ENOENT) { + /* On a Unix system that should never happen. However, I can + imagine this error code on non-inode based systems. */ + log_info(_("can't read `%s': %s\n"), seed_file_name, strerror(errno)); + allow_seed_file_update = 1; + close(fd); + return 0; + } + else if( n == -1 ) { + /* A real read error. */ log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); close(fd); return 0; } + else if ( n != POOLSIZE ) { + log_info(_("WARNING: invalid size of random_seed file - not used\n") ); + close(fd); + return 0; + } close(fd);