diff options
Diffstat (limited to 'debian/patches/Sanity-check-size-when-converting-the-first-record-t.patch')
-rw-r--r-- | debian/patches/Sanity-check-size-when-converting-the-first-record-t.patch | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/debian/patches/Sanity-check-size-when-converting-the-first-record-t.patch b/debian/patches/Sanity-check-size-when-converting-the-first-record-t.patch new file mode 100644 index 0000000..c0964be --- /dev/null +++ b/debian/patches/Sanity-check-size-when-converting-the-first-record-t.patch @@ -0,0 +1,107 @@ +From 586b418ad85ff8c2e756eff7063ffaeca631fa02 Mon Sep 17 00:00:00 2001 +From: "Todd C. Miller" <Todd.Miller@sudo.ws> +Date: Sun, 5 Jan 2020 09:37:09 -0700 +Subject: [PATCH] Sanity check size when converting the first record to + TS_LOCKEXCL Coverity CID 206591 + +[Salvatore Bonaccorso: Backport to 1.8.27: + - Context changes + - Drop hunk about copyright years update + - Cast sizeof(struct timestamp_entry_v1) into ssize_t as 1.8.27 does + not contain the "Add ssizeof macro that returns ssize_t" change. +] +--- + plugins/sudoers/timestamp.c | 65 ++++++++++++++++++++++++++++--------- + 1 file changed, 49 insertions(+), 16 deletions(-) + +--- a/plugins/sudoers/timestamp.c ++++ b/plugins/sudoers/timestamp.c +@@ -611,6 +611,25 @@ done: + } + + /* ++ * Write a TS_LOCKEXCL record at the beginning of the time stamp file. ++ */ ++bool ++timestamp_lock_write(struct ts_cookie *cookie) ++{ ++ struct timestamp_entry entry; ++ bool ret = true; ++ debug_decl(timestamp_lock_write, SUDOERS_DEBUG_AUTH); ++ ++ memset(&entry, 0, sizeof(entry)); ++ entry.version = TS_VERSION; ++ entry.size = sizeof(entry); ++ entry.type = TS_LOCKEXCL; ++ if (ts_write(cookie->fd, cookie->fname, &entry, -1) == -1) ++ ret = false; ++ debug_return_bool(ret); ++} ++ ++/* + * Lock a record in the time stamp file for exclusive access. + * If the record does not exist, it is created (as disabled). + */ +@@ -619,6 +638,7 @@ timestamp_lock(void *vcookie, struct pas + { + struct ts_cookie *cookie = vcookie; + struct timestamp_entry entry; ++ bool overwrite = false; + off_t lock_pos; + ssize_t nread; + debug_decl(timestamp_lock, SUDOERS_DEBUG_AUTH) +@@ -640,26 +660,39 @@ timestamp_lock(void *vcookie, struct pas + /* Make sure the first record is of type TS_LOCKEXCL. */ + memset(&entry, 0, sizeof(entry)); + nread = read(cookie->fd, &entry, sizeof(entry)); +- if (nread == 0) { +- /* New file, add TS_LOCKEXCL record. */ +- entry.version = TS_VERSION; +- entry.size = sizeof(entry); +- entry.type = TS_LOCKEXCL; +- if (ts_write(cookie->fd, cookie->fname, &entry, -1) == -1) +- debug_return_bool(false); ++ if (nread < (ssize_t)sizeof(struct timestamp_entry_v1)) { ++ /* New or invalid time stamp file. */ ++ overwrite = true; + } else if (entry.type != TS_LOCKEXCL) { +- /* Old sudo record, convert it to TS_LOCKEXCL. */ +- entry.type = TS_LOCKEXCL; +- memset((char *)&entry + offsetof(struct timestamp_entry, type), 0, +- nread - offsetof(struct timestamp_entry, type)); +- if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1) +- debug_return_bool(false); ++ if (entry.size == sizeof(struct timestamp_entry_v1)) { ++ /* Old sudo record, convert it to TS_LOCKEXCL. */ ++ entry.type = TS_LOCKEXCL; ++ memset((char *)&entry + offsetof(struct timestamp_entry, type), 0, ++ nread - offsetof(struct timestamp_entry, type)); ++ if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1) ++ debug_return_bool(false); ++ } else { ++ /* Corrupted time stamp file? Just overwrite it. */ ++ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO, ++ "corrupt initial record, type: %hu, size: %hu (expected %zu)", ++ entry.type, entry.size, sizeof(struct timestamp_entry_v1)); ++ overwrite = true; ++ } + } +- if (entry.size != sizeof(entry)) { ++ if (overwrite) { ++ /* Rewrite existing time stamp file or create new one. */ ++ if (ftruncate(cookie->fd, 0) != 0) { ++ sudo_warn(U_("unable to truncate time stamp file to %lld bytes"), ++ 0LL); ++ debug_return_bool(false); ++ } ++ if (!timestamp_lock_write(cookie)) ++ debug_return_bool(false); ++ } else if (entry.size != sizeof(entry)) { + /* Reset position if the lock record has an unexpected size. */ + if (lseek(cookie->fd, entry.size, SEEK_SET) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO, +- "unable to seek to %lld", (long long)entry.size); ++ "unable to seek to %hu", entry.size); + debug_return_bool(false); + } + } |