From a78e6a5ab537ecb2e320438d0819442a8fe2b1f1 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 22 Sep 2016 10:59:11 -0400 Subject: [PATCH] Switch from readdir_r back to readdir. readdir and readdir_r have a sad history: https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html https://womble.decadent.org.uk/readdir_r-advisory.html http://austingroupbugs.net/view.php?id=696 Martin Thomson reports that newer glibcs warn that readdir_r is deprecated. Especially since this has been banished to libdecrepit anyway, go ahead and honor that warning. OpenSSL also uses readdir, so we're no worse than they are. While I'm here, rewrite this to remove a useless layer of abstraction, now that we've punted on supporting most platforms here. Also remove the redundant documentation comment (there's one in the header already). Change-Id: I5350c55417a7f5c4c4725f97dd63f960aeb96801 Reviewed-on: https://boringssl-review.googlesource.com/11220 Reviewed-by: Adam Langley Commit-Queue: Adam Langley CQ-Verified: CQ bot account: commit-bot@chromium.org --- decrepit/ssl/ssl_decrepit.c | 112 +++++++++--------------------------- 1 file changed, 26 insertions(+), 86 deletions(-) diff --git a/decrepit/ssl/ssl_decrepit.c b/decrepit/ssl/ssl_decrepit.c index e25cbf31..12a03da4 100644 --- a/decrepit/ssl/ssl_decrepit.c +++ b/decrepit/ssl/ssl_decrepit.c @@ -114,111 +114,51 @@ #include #include -#include #include #include #include -typedef struct { - DIR *dir; - struct dirent dirent; -} OPENSSL_DIR_CTX; - -static const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, - const char *directory) { - struct dirent *dirent; - - if (ctx == NULL || directory == NULL) { - errno = EINVAL; - return NULL; - } - - errno = 0; - if (*ctx == NULL) { - *ctx = malloc(sizeof(OPENSSL_DIR_CTX)); - if (*ctx == NULL) { - errno = ENOMEM; - return 0; - } - memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX)); - - (*ctx)->dir = opendir(directory); - if ((*ctx)->dir == NULL) { - int save_errno = errno; /* Probably not needed, but I'm paranoid */ - free(*ctx); - *ctx = NULL; - errno = save_errno; - return 0; - } - } - - if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 || - dirent == NULL) { +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *path) { + DIR *dir = opendir(path); + if (dir == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + ERR_add_error_data(3, "opendir('", dir, "')"); return 0; } - return (*ctx)->dirent.d_name; -} - -static int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) { - if (ctx != NULL && *ctx != NULL) { - int r = closedir((*ctx)->dir); - free(*ctx); - *ctx = NULL; - return r == 0; - } - - errno = EINVAL; - return 0; -} - - -/* Add a directory of certs to a stack. - * - * \param stack the stack to append to. - * \param dir the directory to append from. All files in this directory will be - * examined as potential certs. Any that are acceptable to - * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will - * be included. - * \return 1 for success, 0 for failure. Note that in the case of failure some - * certs may have been added to \c stack. */ -int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - const char *dir) { - OPENSSL_DIR_CTX *d = NULL; - const char *filename; int ret = 0; + for (;;) { + /* |readdir| may fail with or without setting |errno|. */ + errno = 0; + struct dirent *dirent = readdir(dir); + if (dirent == NULL) { + if (errno) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + ERR_add_error_data(3, "readdir('", path, "')"); + } else { + ret = 1; + } + break; + } - /* Note that a side effect is that the CAs will be sorted by name */ - while ((filename = OPENSSL_DIR_read(&d, dir))) { char buf[1024]; - int r; - - if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { + if (strlen(path) + strlen(dirent->d_name) + 2 > sizeof(buf)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG); - goto err; + break; } - r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); - if (r <= 0 || r >= (int)sizeof(buf) || + int r = BIO_snprintf(buf, sizeof(buf), "%s/%s", path, dirent->d_name); + if (r <= 0 || + r >= (int)sizeof(buf) || !SSL_add_file_cert_subjects_to_stack(stack, buf)) { - goto err; + break; } } - if (errno) { - OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); - ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); - goto err; - } - - ret = 1; - -err: - if (d) { - OPENSSL_DIR_end(&d); - } + closedir(dir); return ret; }