diff options
author | Werner Koch <[email protected]> | 2012-11-07 17:06:27 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2012-11-07 17:06:27 +0000 |
commit | b1abc01d4ad199258b3d2fb579ac06c6fea747fd (patch) | |
tree | 6a9ff5019a2337e0b5f766b5bef050673a5029c2 | |
parent | Remove trailing white space from one file (diff) | |
download | gnupg-b1abc01d4ad199258b3d2fb579ac06c6fea747fd.tar.gz gnupg-b1abc01d4ad199258b3d2fb579ac06c6fea747fd.zip |
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
-rw-r--r-- | cipher/random.c | 26 |
1 files changed, 25 insertions, 1 deletions
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); |