From ce3a4ac7a3fdf7c83cedc63c9d04dc18c9e69f50 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20G=C3=B6ttsche?= Date: Mon, 11 Dec 2023 17:45:26 +0100 Subject: [PATCH] lib: avoid double close on error log.c:90:24: warning: double 'close' of file descriptor 'fd' [CWE-1341] [-Wanalyzer-fd-double-close] failure.c:94:24: warning: double 'close' of file descriptor 'fd' [CWE-1341] [-Wanalyzer-fd-double-close] failure.c:193:32: warning: double 'close' of file descriptor 'fd' [CWE-1341] [-Wanalyzer-fd-double-close] utmp.c:103:24: warning: double 'close' of file descriptor 'fd' [CWE-1341] [-Wanalyzer-fd-double-close] --- lib/failure.c | 47 ++++++++++++++++++++++++++++++++++++----------- lib/log.c | 24 ++++++++++++++++++------ lib/utmp.c | 23 ++++++++++++++++++----- 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/lib/failure.c b/lib/failure.c index cb22694ac..376b102b4 100644 --- a/lib/failure.c +++ b/lib/failure.c @@ -90,13 +90,26 @@ void failure (uid_t uid, const char *tty, struct faillog *fl) */ if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write_full(fd, fl, sizeof *fl) == -1) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't write faillog entry for UID %lu in %s: %m", - (unsigned long) uid, FAILLOG_FILE)); + || (write_full(fd, fl, sizeof *fl) == -1)) { + goto err_write; + } + + if (close (fd) != 0 && errno != EINTR) { + goto err_close; + } + + return; + +err_write: + { + int saved_errno = errno; (void) close (fd); + errno = saved_errno; } +err_close: + SYSLOG ((LOG_WARN, + "Can't write faillog entry for UID %lu to %s: %m", + (unsigned long) uid, FAILLOG_FILE)); } static bool too_many_failures (const struct faillog *fl) @@ -189,18 +202,30 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed) fail.fail_cnt = 0; if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write_full(fd, &fail, sizeof fail) == -1) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't reset faillog entry for UID %lu in %s: %m", - (unsigned long) uid, FAILLOG_FILE)); - (void) close (fd); + || (write_full(fd, &fail, sizeof fail) == -1)) { + goto err_write; + } + + if (close (fd) != 0 && errno != EINTR) { + goto err_close; } } else { (void) close (fd); } return 1; + +err_write: + { + int saved_errno = errno; + (void) close (fd); + errno = saved_errno; + } +err_close: + SYSLOG ((LOG_WARN, + "Can't reset faillog entry for UID %lu in %s: %m", + (unsigned long) uid, FAILLOG_FILE)); + return 1; } /* diff --git a/lib/log.c b/lib/log.c index c6801185a..fd7ee1309 100644 --- a/lib/log.c +++ b/lib/log.c @@ -86,12 +86,24 @@ void dolastlog ( STRNCPY(newlog.ll_host, host); #endif if ( (lseek (fd, offset, SEEK_SET) != offset) - || (write_full(fd, &newlog, sizeof newlog) == -1) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't write lastlog entry for UID %lu in %s.", - (unsigned long) pw->pw_uid, LASTLOG_FILE)); + || (write_full(fd, &newlog, sizeof newlog) == -1)) { + goto err_write; + } + + if (close (fd) != 0 && errno != EINTR) { + goto err_close; + } + + return; + +err_write: + { + int saved_errno = errno; (void) close (fd); + errno = saved_errno; } +err_close: + SYSLOG ((LOG_WARN, + "Can't write lastlog entry for UID %lu in %s: %m", + (unsigned long) pw->pw_uid, LASTLOG_FILE)); } - diff --git a/lib/utmp.c b/lib/utmp.c index 5ac5ecd6a..e7c33a2b2 100644 --- a/lib/utmp.c +++ b/lib/utmp.c @@ -99,13 +99,26 @@ static void failtmp (const char *username, const struct utmp *failent) * Append the new failure record and close the log file. */ - if ( (write_full(fd, failent, sizeof *failent) == -1) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't append failure of user %s to %s: %m", - username, ftmp)); + if (write_full(fd, failent, sizeof *failent) == -1) { + goto err_write; + } + + if (close (fd) != 0 && errno != EINTR) { + goto err_close; + } + + return; + +err_write: + { + int saved_errno = errno; (void) close (fd); + errno = saved_errno; } +err_close: + SYSLOG ((LOG_WARN, + "Can't append failure of user %s to %s: %m", + username, ftmp)); } /* -- 2.47.2