From 96f2687b8073cdcf667e9fd8d237f44a1434348b Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 25 May 2020 10:09:28 +0200 Subject: lib: avoid file descriptor leak when application forks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes use of the "e" flag of fopen, provided by the Gnulib's fopen-gnu module. Reported by Remi Denis-Courmont in: https://gitlab.com/gnutls/gnutls/-/issues/985 and fix suggested by Tim Rühsen. Signed-off-by: Daiki Ueno --- bootstrap.conf | 4 ++-- lib/auth/psk_passwd.c | 2 +- lib/auth/srp_passwd.c | 4 ++-- lib/file.c | 2 +- lib/fips.c | 2 +- lib/kx.c | 2 +- lib/pkcs11.c | 2 +- lib/priority.c | 10 +++++++++- lib/verify-tofu.c | 6 +++--- 9 files changed, 21 insertions(+), 13 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index dcf346d6c6..3abfe10464 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -25,10 +25,10 @@ checkout_only_file= local_gl_dir=gl/override/ required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/tlsfuzzer tests/suite/tls-fuzzer/tlslite-ng devel/nettle devel/libtasn1" -# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat time_r unistd vasprintf verify vsnprintf warnings +# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat time_r unistd vasprintf verify vsnprintf warnings gnulib_modules=" -alloca attribute byteswap c-ctype c-strcase extensions func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types time_r unistd valgrind-tests vasprintf verify vsnprintf warnings +alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types time_r unistd valgrind-tests vasprintf verify vsnprintf warnings " unistring_modules=" diff --git a/lib/auth/psk_passwd.c b/lib/auth/psk_passwd.c index a0427914f9..7384703bc7 100644 --- a/lib/auth/psk_passwd.c +++ b/lib/auth/psk_passwd.c @@ -203,7 +203,7 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, /* Open the selected password file. */ - fd = fopen(cred->password_file, "r"); + fd = fopen(cred->password_file, "re"); if (fd == NULL) { gnutls_assert(); return GNUTLS_E_SRP_PWD_ERROR; diff --git a/lib/auth/srp_passwd.c b/lib/auth/srp_passwd.c index baa4086e77..78848cdf10 100644 --- a/lib/auth/srp_passwd.c +++ b/lib/auth/srp_passwd.c @@ -202,7 +202,7 @@ pwd_read_conf(const char *pconf_file, SRP_PWD_ENTRY * entry, int idx) snprintf(indexstr, sizeof(indexstr), "%u", (unsigned int) idx); - fd = fopen(pconf_file, "r"); + fd = fopen(pconf_file, "re"); if (fd == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; @@ -308,7 +308,7 @@ _gnutls_srp_pwd_read_entry(gnutls_session_t state, char *username, /* Open the selected password file. */ - fd = fopen(cred->password_file, "r"); + fd = fopen(cred->password_file, "re"); if (fd == NULL) { gnutls_assert(); ret = GNUTLS_E_SRP_PWD_ERROR; diff --git a/lib/file.c b/lib/file.c index 2bcdee8b7e..03aa265c38 100644 --- a/lib/file.c +++ b/lib/file.c @@ -29,7 +29,7 @@ int _gnutls_file_exists(const char *file) { FILE *fd; - fd = fopen(file, "r"); + fd = fopen(file, "re"); if (fd == NULL) return -1; diff --git a/lib/fips.c b/lib/fips.c index 3c43250aaf..0f0c34c1df 100644 --- a/lib/fips.c +++ b/lib/fips.c @@ -93,7 +93,7 @@ unsigned _gnutls_fips_mode_enabled(void) goto exit; } - fd = fopen(FIPS_KERNEL_FILE, "r"); + fd = fopen(FIPS_KERNEL_FILE, "re"); if (fd != NULL) { f1p = fgetc(fd); fclose(fd); diff --git a/lib/kx.c b/lib/kx.c index a874f15114..1eda14d3d6 100644 --- a/lib/kx.c +++ b/lib/kx.c @@ -143,7 +143,7 @@ void _gnutls_nss_keylog_write(gnutls_session_t session, checked_env = 1; keylogfile = secure_getenv("SSLKEYLOGFILE"); if (keylogfile != NULL) - keylog = fopen(keylogfile, "a"); + keylog = fopen(keylogfile, "ae"); } if (keylog) { diff --git a/lib/pkcs11.c b/lib/pkcs11.c index d03bf6e444..fad16aaf4f 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -889,7 +889,7 @@ static void compat_load(const char *configfile) if (configfile == NULL) configfile = "/etc/gnutls/pkcs11.conf"; - fp = fopen(configfile, "r"); + fp = fopen(configfile, "re"); if (fp == NULL) { gnutls_assert(); return; diff --git a/lib/priority.c b/lib/priority.c index ad99459adb..0a284ae1f1 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -1304,6 +1304,7 @@ static void _gnutls_update_system_priorities(void) { int ret; struct stat sb; + FILE *fp; if (stat(system_priority_file, &sb) < 0) { _gnutls_debug_log("cfg: unable to access: %s: %d\n", @@ -1321,7 +1322,14 @@ static void _gnutls_update_system_priorities(void) if (system_wide_priority_strings_init != 0) _name_val_array_clear(&system_wide_priority_strings); - ret = ini_parse(system_priority_file, cfg_ini_handler, NULL); + fp = fopen(system_priority_file, "re"); + if (fp == NULL) { + _gnutls_debug_log("cfg: unable to open: %s: %d\n", + system_priority_file, errno); + return; + } + ret = ini_parse_file(fp, cfg_ini_handler, NULL); + fclose(fp); if (ret != 0) { _gnutls_debug_log("cfg: unable to parse: %s: %d\n", system_priority_file, ret); diff --git a/lib/verify-tofu.c b/lib/verify-tofu.c index 36328e04af..8baebaa011 100644 --- a/lib/verify-tofu.c +++ b/lib/verify-tofu.c @@ -343,7 +343,7 @@ static int verify_pubkey(const char *file, if (service != NULL) service_len = strlen(service); - fd = fopen(file, "rb"); + fd = fopen(file, "rbe"); if (fd == NULL) { ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; @@ -414,7 +414,7 @@ int store_pubkey(const char *db_name, const char *host, goto cleanup; } - fd = fopen(db_name, "ab+"); + fd = fopen(db_name, "abe+"); if (fd == NULL) { ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; @@ -449,7 +449,7 @@ int store_commitment(const char *db_name, const char *host, FILE *fd; char buffer[MAX_HASH_SIZE * 2 + 1]; - fd = fopen(db_name, "ab+"); + fd = fopen(db_name, "abe+"); if (fd == NULL) return gnutls_assert_val(GNUTLS_E_FILE_ERROR); -- cgit v1.2.1