diff --git a/backport-0001-CVE-2021-3156-Reset-valid_flags.patch b/backport-0001-CVE-2021-3156-Reset-valid_flags.patch deleted file mode 100644 index d42d269f708a329e367cd101d50418c6f60d4fc0..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2021-3156-Reset-valid_flags.patch +++ /dev/null @@ -1,90 +0,0 @@ -# HG changeset patch -# Parent 111fde52d1166af65b622da6eae19791ce0e8871 -Reset valid_flags to MODE_NONINTERACTIVE for sudoedit. -This is consistent with how the -e option is handled. -Also reject -H and -P flags for sudoedit as was done in sudo 1.7. -Found by Qualys. - ---- a/src/parse_args.c -+++ b/src/parse_args.c -@@ -114,7 +114,10 @@ struct environment { - /* - * Default flags allowed when running a command. - */ --#define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_SHELL) -+#define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_PRESERVE_GROUPS|MODE_SHELL) -+#define EDIT_VALID_FLAGS MODE_NONINTERACTIVE -+#define LIST_VALID_FLAGS (MODE_NONINTERACTIVE|MODE_LONG_LIST) -+#define VALIDATE_VALID_FLAGS MODE_NONINTERACTIVE - - /* Option number for the --host long option due to ambiguity of the -h flag. */ - #define OPT_HOSTNAME 256 -@@ -257,6 +260,7 @@ parse_args(int argc, char **argv, int *o - progname = "sudoedit"; - mode = MODE_EDIT; - sudo_settings[ARG_SUDOEDIT].value = "true"; -+ valid_flags = EDIT_VALID_FLAGS; - } - - /* Load local IP addresses and masks. */ -@@ -354,7 +358,7 @@ parse_args(int argc, char **argv, int *o - usage_excl(); - mode = MODE_EDIT; - sudo_settings[ARG_SUDOEDIT].value = "true"; -- valid_flags = MODE_NONINTERACTIVE; -+ valid_flags = EDIT_VALID_FLAGS; - break; - case 'g': - assert(optarg != NULL); -@@ -366,6 +370,7 @@ parse_args(int argc, char **argv, int *o - break; - case 'H': - sudo_settings[ARG_SET_HOME].value = "true"; -+ SET(flags, MODE_RESET_HOME); - break; - case 'h': - if (optarg == NULL) { -@@ -420,7 +425,7 @@ parse_args(int argc, char **argv, int *o - usage_excl(); - } - mode = MODE_LIST; -- valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST; -+ valid_flags = LIST_VALID_FLAGS; - break; - case 'n': - SET(flags, MODE_NONINTERACTIVE); -@@ -428,6 +433,7 @@ parse_args(int argc, char **argv, int *o - break; - case 'P': - sudo_settings[ARG_PRESERVE_GROUPS].value = "true"; -+ SET(flags, MODE_PRESERVE_GROUPS); - break; - case 'p': - /* An empty prompt is allowed. */ -@@ -486,7 +492,7 @@ parse_args(int argc, char **argv, int *o - if (mode && mode != MODE_VALIDATE) - usage_excl(); - mode = MODE_VALIDATE; -- valid_flags = MODE_NONINTERACTIVE; -+ valid_flags = VALIDATE_VALID_FLAGS; - break; - case 'V': - if (mode && mode != MODE_VERSION) -@@ -514,7 +520,7 @@ parse_args(int argc, char **argv, int *o - if (!mode) { - /* Defer -k mode setting until we know whether it is a flag or not */ - if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) { -- if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) { -+ if (argc == 0 && !ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL)) { - mode = MODE_INVALIDATE; /* -k by itself */ - sudo_settings[ARG_IGNORE_TICKET].value = NULL; - valid_flags = 0; -@@ -578,7 +584,7 @@ parse_args(int argc, char **argv, int *o - /* - * For shell mode we need to rewrite argv - */ -- if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) { -+ if (ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL) && ISSET(mode, MODE_RUN)) { - char **av, *cmnd = NULL; - int ac = 1; - diff --git a/backport-0002-CVE-2021-3156-Add-sudoedit-flag-checks.patch b/backport-0002-CVE-2021-3156-Add-sudoedit-flag-checks.patch deleted file mode 100644 index 4d11cf2d3309f93e9f45473c41ad9f2e424eb078..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2021-3156-Add-sudoedit-flag-checks.patch +++ /dev/null @@ -1,35 +0,0 @@ -# HG changeset patch -# Parent 4e0af3ef53d71d1e0d1ee5894a0c078020ab391a -Add sudoedit flag checks in plugin that are consistent with front-end. -Don't assume the sudo front-end is sending reasonable mode flags. -These checks need to be kept consistent between the sudo front-end -and the sudoers plugin. - ---- a/plugins/sudoers/policy.c -+++ b/plugins/sudoers/policy.c -@@ -87,10 +87,11 @@ parse_bool(const char *line, int varlen, - int - sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) - { -+ const int edit_mask = MODE_EDIT|MODE_IGNORE_TICKET|MODE_NONINTERACTIVE; - struct sudoers_open_info *info = v; -- char * const *cur; - const char *p, *errstr, *groups = NULL; - const char *remhost = NULL; -+ char * const *cur; - int flags = 0; - debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN); - -@@ -319,6 +320,12 @@ sudoers_policy_deserialize_info(void *v, - #endif - } - -+ /* Sudo front-end should restrict mode flags for sudoedit. */ -+ if (ISSET(flags, MODE_EDIT) && (flags & edit_mask) != flags) { -+ sudo_warnx(U_("invalid mode flags from sudo front end: 0x%x"), flags); -+ goto bad; -+ } -+ - user_gid = (gid_t)-1; - user_sid = (pid_t)-1; - user_uid = (gid_t)-1; diff --git a/backport-0003-CVE-2021-3156-Fix-potential-buffer-overflow.patch b/backport-0003-CVE-2021-3156-Fix-potential-buffer-overflow.patch deleted file mode 100644 index 4e5b6192586254a972c84396f2b385d963ccf7e2..0000000000000000000000000000000000000000 --- a/backport-0003-CVE-2021-3156-Fix-potential-buffer-overflow.patch +++ /dev/null @@ -1,65 +0,0 @@ -Backport of: - -# HG changeset patch -# Parent 9b29e05ea310e187e41d8bcb58eddef8bd8b70d3 -Fix potential buffer overflow when unescaping backslashes in user_args. -Do not try to unescaping backslashes unless in run mode *and* we are -running the command via a shell. -Found by Qualys. - ---- a/plugins/sudoers/sudoers.c -+++ b/plugins/sudoers/sudoers.c -@@ -478,7 +478,7 @@ sudoers_policy_main(int argc, char * con - - /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ - /* XXX - causes confusion when root is not listed in sudoers */ -- if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) { -+ if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) { - if (user_uid == 0 && strcmp(prev_user, "root") != 0) { - struct passwd *pw; - -@@ -854,8 +854,8 @@ set_cmnd(void) - if (user_cmnd == NULL) - user_cmnd = NewArgv[0]; - -- if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { -- if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) { -+ if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) { -+ if (!ISSET(sudo_mode, MODE_EDIT)) { - if (def_secure_path && !user_is_exempt()) - path = def_secure_path; - if (!set_perms(PERM_RUNAS)) -@@ -894,7 +894,8 @@ set_cmnd(void) - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_int(-1); - } -- if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { -+ if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) && -+ ISSET(sudo_mode, MODE_RUN)) { - /* - * When running a command via a shell, the sudo front-end - * escapes potential meta chars. We unescape non-spaces -@@ -902,10 +903,22 @@ set_cmnd(void) - */ - for (to = user_args, av = NewArgv + 1; (from = *av); av++) { - while (*from) { -- if (from[0] == '\\' && !isspace((unsigned char)from[1])) -+ if (from[0] == '\\' && from[1] != '\0' && -+ !isspace((unsigned char)from[1])) { - from++; -+ } -+ if (size - (to - user_args) < 1) { -+ sudo_warnx(U_("internal error, %s overflow"), -+ __func__); -+ debug_return_int(NOT_FOUND_ERROR); -+ } - *to++ = *from++; - } -+ if (size - (to - user_args) < 1) { -+ sudo_warnx(U_("internal error, %s overflow"), -+ __func__); -+ debug_return_int(NOT_FOUND_ERROR); -+ } - *to++ = ' '; - } - *--to = '\0'; diff --git a/backport-0004-CVE-2021-3156-Fix-the-memset-offset.patch b/backport-0004-CVE-2021-3156-Fix-the-memset-offset.patch deleted file mode 100644 index 5adaa856a22988c69a19190b2390d76ec4eab2c8..0000000000000000000000000000000000000000 --- a/backport-0004-CVE-2021-3156-Fix-the-memset-offset.patch +++ /dev/null @@ -1,19 +0,0 @@ -# HG changeset patch -# Parent 5c6c54c8f971dfa21977935328942a57591ce5a8 -Fix the memset offset when converting a v1 timestamp to TS_LOCKEXCL. -We want to zero the struct starting at flags, not type (which was just set). -Found by Qualys. - ---- a/plugins/sudoers/timestamp.c -+++ b/plugins/sudoers/timestamp.c -@@ -662,8 +662,8 @@ timestamp_lock(void *vcookie, struct pas - 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)); -+ memset((char *)&entry + offsetof(struct timestamp_entry, flags), 0, -+ nread - offsetof(struct timestamp_entry, flags)); - if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1) - debug_return_bool(false); - } else { diff --git a/backport-0005-CVE-2021-3156-Dont-assume-that-argv.patch b/backport-0005-CVE-2021-3156-Dont-assume-that-argv.patch deleted file mode 100644 index 8bdd69535c7c40857cab603f241824a2312946ac..0000000000000000000000000000000000000000 --- a/backport-0005-CVE-2021-3156-Dont-assume-that-argv.patch +++ /dev/null @@ -1,31 +0,0 @@ -# HG changeset patch -# Parent a84c8fe05da6097efaa00d8dee8a07b5816ae84e -Don't assume that argv is allocated as a single flat buffer. -While this is how the kernel behaves it is not a portable assumption. -The assumption may also be violated if getopt_long(3) permutes arguments. -Found by Qualys. - ---- a/src/parse_args.c -+++ b/src/parse_args.c -@@ -591,16 +591,16 @@ parse_args(int argc, char **argv, int *o - if (argc != 0) { - /* shell -c "command" */ - char *src, *dst; -- size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) + -- strlen(argv[argc - 1]) + 1; -+ size_t size = 0; - -- cmnd = dst = reallocarray(NULL, cmnd_size, 2); -- if (cmnd == NULL) -+ for (av = argv; *av != NULL; av++) -+ size += strlen(*av) + 1; -+ if (size == 0 || (cmnd = reallocarray(NULL, size, 2)) == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (!gc_add(GC_PTR, cmnd)) - exit(EXIT_FAILURE); - -- for (av = argv; *av != NULL; av++) { -+ for (dst = cmnd, av = argv; *av != NULL; av++) { - for (src = *av; *src != '\0'; src++) { - /* quote potential meta characters */ - if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$') diff --git a/backport-CVE-2021-23239-Fix-potential-directory.patch b/backport-CVE-2021-23239-Fix-potential-directory.patch deleted file mode 100644 index 59eb2a0ee46fac314803cb1f04787a7624879d37..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-23239-Fix-potential-directory.patch +++ /dev/null @@ -1,58 +0,0 @@ -From db1f27c0350e9e437c93780ffe88648ae1984467 Mon Sep 17 00:00:00 2001 -From: "Todd C. Miller" -Date: Wed, 6 Jan 2021 10:16:00 -0700 -Subject: [PATCH] Fix potential directory existing info leak in sudoedit. When - creating a new file, sudoedit checks to make sure the parent directory exists - so it can provide the user with a sensible error message. However, this - could be used to test for the existence of directories not normally - accessible to the user by pointing to them with a symbolic link when the - parent directory is controlled by the user. Problem reported by Matthias - Gerstner of SUSE. - ---- - src/sudo_edit.c | 29 ++++++++++++++++++++++++----- - 1 file changed, 24 insertions(+), 5 deletions(-) - -diff --git a/src/sudo_edit.c b/src/sudo_edit.c -index 82e04a71b..5502b7bd9 100644 ---- a/src/sudo_edit.c -+++ b/src/sudo_edit.c -@@ -541,14 +541,33 @@ sudo_edit_create_tfiles(struct command_details *command_details, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details); - if (ofd != -1 || errno == ENOENT) { - if (ofd == -1) { -- /* New file, verify parent dir exists unless in cwd. */ -+ /* -+ * New file, verify parent dir exists unless in cwd. -+ * This fails early so the user knows ahead of time if the -+ * edit won't succeed. Additional checks are performed -+ * when copying the temporary file back to the origin. -+ */ - char *slash = strrchr(files[i], '/'); - if (slash != NULL && slash != files[i]) { -- int serrno = errno; -+ const int sflags = command_details->flags; -+ const int serrno = errno; -+ int dfd; -+ -+ /* -+ * The parent directory is allowed to be a symbolic -+ * link as long as *its* parent is not writable. -+ */ - *slash = '\0'; -- if (stat(files[i], &sb) == 0 && S_ISDIR(sb.st_mode)) { -- memset(&sb, 0, sizeof(sb)); -- rc = 0; -+ SET(command_details->flags, CD_SUDOEDIT_FOLLOW); -+ dfd = sudo_edit_open(files[i], DIR_OPEN_FLAGS, -+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details); -+ command_details->flags = sflags; -+ if (dfd != -1) { -+ if (fstat(dfd, &sb) == 0 && S_ISDIR(sb.st_mode)) { -+ memset(&sb, 0, sizeof(sb)); -+ rc = 0; -+ } -+ close(dfd); - } - *slash = '/'; - errno = serrno; diff --git a/backport-CVE-2021-23240-Add-security-checks.patch b/backport-CVE-2021-23240-Add-security-checks.patch deleted file mode 100644 index 6ce05dcf51e76173f576df8a25aa4237bddfc93a..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-23240-Add-security-checks.patch +++ /dev/null @@ -1,422 +0,0 @@ -From 7cd36222e765d8fc561e5a52a59a1c3a4feb38bb Mon Sep 17 00:00:00 2001 -From: "Todd C. Miller" -Date: Wed, 6 Jan 2021 10:16:00 -0700 -Subject: [PATCH] Add security checks before using temp files for SELinux RBAC - sudoedit. Otherwise, it may be possible for the user running sudoedit to - replace the newly-created temporary files with a symbolic link and have - sudoedit set the owner of an arbitrary file. Problem reported by Matthias - Gerstner of SUSE. - ---- - src/copy_file.c | 35 +++++++++++++++- - src/sesh.c | 27 ++++++++----- - src/sudo_edit.c | 104 +++++++++++++++++++++++++++++++----------------- - src/sudo_exec.h | 4 +- - 4 files changed, 121 insertions(+), 49 deletions(-) - -diff --git a/src/copy_file.c b/src/copy_file.c -index a90a3743c..08a59fe11 100644 ---- a/src/copy_file.c -+++ b/src/copy_file.c -@@ -1,7 +1,7 @@ - /* - * SPDX-License-Identifier: ISC - * -- * Copyright (c) 2020 Todd C. Miller -+ * Copyright (c) 2020-2021 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above -@@ -23,6 +23,8 @@ - - #include - -+#include -+ - #include - #include - #include -@@ -134,3 +136,34 @@ sudo_copy_file(const char *src, int src_fd, off_t src_len, const char *dst, - sudo_warn(U_("unable to write to %s"), dst); - debug_return_int(-1); - } -+ -+#ifdef HAVE_SELINUX -+bool -+sudo_check_temp_file(int tfd, const char *tfile, uid_t uid, struct stat *sb) -+{ -+ struct stat sbuf; -+ debug_decl(sudo_check_temp_file, SUDO_DEBUG_UTIL); -+ -+ if (sb == NULL) -+ sb = &sbuf; -+ -+ if (fstat(tfd, sb) == -1) { -+ sudo_warn(U_("unable to stat %s"), tfile); -+ debug_return_bool(false); -+ } -+ if (!S_ISREG(sb->st_mode)) { -+ sudo_warnx(U_("%s: not a regular file"), tfile); -+ debug_return_bool(false); -+ } -+ if ((sb->st_mode & ALLPERMS) != (S_IRUSR|S_IWUSR)) { -+ sudo_warnx(U_("%s: bad file mode: 0%o"), tfile, sb->st_mode & ALLPERMS); -+ debug_return_bool(false); -+ } -+ if (sb->st_uid != uid) { -+ sudo_warnx(U_("%s is owned by uid %u, should be %u"), -+ tfile, (unsigned int)sb->st_uid, (unsigned int)uid); -+ debug_return_bool(false); -+ } -+ debug_return_bool(true); -+} -+#endif /* SELINUX */ -diff --git a/src/sesh.c b/src/sesh.c -index 8241f13f1..abbef2577 100644 ---- a/src/sesh.c -+++ b/src/sesh.c -@@ -1,7 +1,7 @@ - /* - * SPDX-License-Identifier: ISC - * -- * Copyright (c) 2008, 2010-2018, 2020 Todd C. Miller -+ * Copyright (c) 2008, 2010-2018, 2020-2021 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above -@@ -132,7 +132,7 @@ main(int argc, char *argv[], char *envp[]) - static int - sesh_sudoedit(int argc, char *argv[]) - { -- int i, oflags_dst, post, ret = SESH_ERR_FAILURE; -+ int i, oflags_src, oflags_dst, post, ret = SESH_ERR_FAILURE; - int fd_src = -1, fd_dst = -1, follow = 0; - struct stat sb; - struct timespec times[2]; -@@ -174,10 +174,12 @@ sesh_sudoedit(int argc, char *argv[]) - debug_return_int(SESH_ERR_BAD_PATHS); - - /* -- * Use O_EXCL if we are not in the post editing stage -- * so that it's ensured that the temporary files are -- * created by us and that we are not opening any symlinks. -+ * In the pre-editing stage, use O_EXCL to ensure that the temporary -+ * files are created by us and that we are not opening any symlinks. -+ * In the post-editing stage, use O_NOFOLLOW so we don't follow symlinks -+ * when opening the temporary files. - */ -+ oflags_src = O_RDONLY|(post ? O_NONBLOCK|O_NOFOLLOW : follow); - oflags_dst = O_WRONLY|O_CREAT|(post ? follow : O_EXCL); - for (i = 0; i < argc - 1; i += 2) { - const char *path_src = argv[i]; -@@ -187,7 +189,7 @@ sesh_sudoedit(int argc, char *argv[]) - * doesn't exist, that's OK, we'll create an empty - * destination file. - */ -- if ((fd_src = open(path_src, O_RDONLY|follow, S_IRUSR|S_IWUSR)) < 0) { -+ if ((fd_src = open(path_src, oflags_src, S_IRUSR|S_IWUSR)) < 0) { - if (errno != ENOENT) { - sudo_warn("%s", path_src); - if (post) { -@@ -197,6 +199,14 @@ sesh_sudoedit(int argc, char *argv[]) - goto cleanup_0; - } - } -+ if (post) { -+ /* Make sure the temporary file is safe and has the proper owner. */ -+ if (!sudo_check_temp_file(fd_src, path_src, geteuid(), &sb)) { -+ ret = SESH_ERR_SOME_FILES; -+ goto nocleanup; -+ } -+ fcntl(fd_src, F_SETFL, fcntl(fd_src, F_GETFL, 0) & ~O_NONBLOCK); -+ } - - if ((fd_dst = open(path_dst, oflags_dst, post ? - (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) : (S_IRUSR|S_IWUSR))) < 0) { -@@ -214,10 +224,7 @@ sesh_sudoedit(int argc, char *argv[]) - off_t len_dst = -1; - - if (post) { -- if (fstat(fd_src, &sb) != 0) { -- ret = SESH_ERR_SOME_FILES; -- goto nocleanup; -- } -+ /* sudo_check_temp_file() filled in sb for us. */ - len_src = sb.st_size; - if (fstat(fd_dst, &sb) != 0) { - ret = SESH_ERR_SOME_FILES; -diff --git a/src/sudo_edit.c b/src/sudo_edit.c -index 5502b7bd9..93810c346 100644 ---- a/src/sudo_edit.c -+++ b/src/sudo_edit.c -@@ -1,7 +1,7 @@ - /* - * SPDX-License-Identifier: ISC - * -- * Copyright (c) 2004-2008, 2010-2020 Todd C. Miller -+ * Copyright (c) 2004-2008, 2010-2021 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above -@@ -259,8 +259,10 @@ sudo_edit_mktemp(const char *ofile, char **tfile) - } else { - len = asprintf(tfile, "%s/%s.XXXXXXXX", edit_tmpdir, cp); - } -- if (len == -1) -- sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); -+ if (len == -1) { -+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); -+ debug_return_int(-1); -+ } - tfd = mkstemps(*tfile, suff ? strlen(suff) : 0); - sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, - "%s -> %s, fd %d", ofile, *tfile, tfd); -@@ -735,7 +737,8 @@ sudo_edit_copy_tfiles(struct command_details *command_details, - - #ifdef HAVE_SELINUX - static int --selinux_run_helper(char *argv[], char *envp[]) -+selinux_run_helper(uid_t uid, gid_t gid, int ngroups, GETGROUPS_T *groups, -+ char *const argv[], char *const envp[]) - { - int status, ret = SESH_ERR_FAILURE; - const char *sesh; -@@ -755,8 +758,10 @@ selinux_run_helper(char *argv[], char *envp[]) - break; - case 0: - /* child runs sesh in new context */ -- if (selinux_setcon() == 0) -+ if (selinux_setcon() == 0) { -+ switch_user(uid, gid, ngroups, groups); - execve(sesh, argv, envp); -+ } - _exit(SESH_ERR_FAILURE); - default: - /* parent waits */ -@@ -775,7 +780,7 @@ selinux_edit_create_tfiles(struct command_details *command_details, - struct tempfile *tf, char *files[], int nfiles) - { - char **sesh_args, **sesh_ap; -- int i, rc, sesh_nargs; -+ int i, error, sesh_nargs, ret = -1; - struct stat sb; - debug_decl(selinux_edit_create_tfiles, SUDO_DEBUG_EDIT); - -@@ -787,7 +792,7 @@ selinux_edit_create_tfiles(struct command_details *command_details, - sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *)); - if (sesh_args == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); -- debug_return_int(-1); -+ goto done; - } - *sesh_ap++ = "sesh"; - *sesh_ap++ = "-e"; -@@ -795,7 +800,6 @@ selinux_edit_create_tfiles(struct command_details *command_details, - *sesh_ap++ = "-h"; - *sesh_ap++ = "0"; - -- /* XXX - temp files should be created with user's context */ - for (i = 0; i < nfiles; i++) { - char *tfile, *ofile = files[i]; - int tfd; -@@ -813,8 +817,7 @@ selinux_edit_create_tfiles(struct command_details *command_details, - if (tfd == -1) { - sudo_warn("mkstemps"); - free(tfile); -- free(sesh_args); -- debug_return_int(-1); -+ goto done; - } - /* Helper will re-create temp file with proper security context. */ - close(tfd); -@@ -825,8 +828,10 @@ selinux_edit_create_tfiles(struct command_details *command_details, - *sesh_ap = NULL; - - /* Run sesh -e [-h] 0 ... */ -- rc = selinux_run_helper(sesh_args, command_details->envp); -- switch (rc) { -+ error = selinux_run_helper(command_details->uid, command_details->gid, -+ command_details->ngroups, command_details->groups, sesh_args, -+ command_details->envp); -+ switch (error) { - case SESH_SUCCESS: - break; - case SESH_ERR_BAD_PATHS: -@@ -836,21 +841,35 @@ selinux_edit_create_tfiles(struct command_details *command_details, - case SESH_ERR_KILLED: - sudo_fatalx("%s", U_("sesh: killed by a signal")); - default: -- sudo_fatalx(U_("sesh: unknown error %d"), rc); -+ sudo_warnx(U_("sesh: unknown error %d"), error); -+ goto done; - } - -- /* Chown to user's UID so they can edit the temporary files. */ - for (i = 0; i < nfiles; i++) { -- if (chown(tf[i].tfile, user_details.uid, user_details.gid) != 0) { -+ int tfd = open(tf[i].tfile, O_RDONLY|O_NONBLOCK|O_NOFOLLOW); -+ if (tfd == -1) { -+ sudo_warn(U_("unable to open %s"), tf[i].tfile); -+ goto done; -+ } -+ if (!sudo_check_temp_file(tfd, tf[i].tfile, command_details->uid, NULL)) { -+ close(tfd); -+ goto done; -+ } -+ if (fchown(tfd, user_details.uid, user_details.gid) != 0) { - sudo_warn("unable to chown(%s) to %d:%d for editing", - tf[i].tfile, user_details.uid, user_details.gid); -+ close(tfd); -+ goto done; - } -+ close(tfd); - } -+ ret = nfiles; - -+done: - /* Contents of tf will be freed by caller. */ - free(sesh_args); - -- return (nfiles); -+ debug_return_int(ret); - } - - static int -@@ -858,7 +877,8 @@ selinux_edit_copy_tfiles(struct command_details *command_details, - struct tempfile *tf, int nfiles, struct timespec *times) - { - char **sesh_args, **sesh_ap; -- int i, rc, sesh_nargs, ret = 1; -+ int i, error, sesh_nargs, ret = 1; -+ int tfd = -1; - struct timespec ts; - struct stat sb; - debug_decl(selinux_edit_copy_tfiles, SUDO_DEBUG_EDIT); -@@ -879,33 +899,43 @@ selinux_edit_copy_tfiles(struct command_details *command_details, - - /* Construct args for sesh -e 1 */ - for (i = 0; i < nfiles; i++) { -- if (stat(tf[i].tfile, &sb) == 0) { -- mtim_get(&sb, ts); -- if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { -- /* -- * If mtime and size match but the user spent no measurable -- * time in the editor we can't tell if the file was changed. -- */ -- if (sudo_timespeccmp(×[0], ×[1], !=)) { -- sudo_warnx(U_("%s unchanged"), tf[i].ofile); -- unlink(tf[i].tfile); -- continue; -- } -+ if (tfd != -1) -+ close(tfd); -+ if ((tfd = open(tf[i].tfile, O_RDONLY|O_NONBLOCK|O_NOFOLLOW)) == -1) { -+ sudo_warn(U_("unable to open %s"), tf[i].tfile); -+ continue; -+ } -+ if (!sudo_check_temp_file(tfd, tf[i].tfile, user_details.uid, &sb)) -+ continue; -+ mtim_get(&sb, ts); -+ if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { -+ /* -+ * If mtime and size match but the user spent no measurable -+ * time in the editor we can't tell if the file was changed. -+ */ -+ if (sudo_timespeccmp(×[0], ×[1], !=)) { -+ sudo_warnx(U_("%s unchanged"), tf[i].ofile); -+ unlink(tf[i].tfile); -+ continue; - } - } - *sesh_ap++ = tf[i].tfile; - *sesh_ap++ = tf[i].ofile; -- if (chown(tf[i].tfile, command_details->uid, command_details->gid) != 0) { -+ if (fchown(tfd, command_details->uid, command_details->gid) != 0) { - sudo_warn("unable to chown(%s) back to %d:%d", tf[i].tfile, - command_details->uid, command_details->gid); - } - } - *sesh_ap = NULL; -+ if (tfd != -1) -+ close(tfd); - - if (sesh_ap - sesh_args > 3) { - /* Run sesh -e 1 ... */ -- rc = selinux_run_helper(sesh_args, command_details->envp); -- switch (rc) { -+ error = selinux_run_helper(command_details->uid, command_details->gid, -+ command_details->ngroups, command_details->groups, sesh_args, -+ command_details->envp); -+ switch (error) { - case SESH_SUCCESS: - ret = 0; - break; -@@ -921,7 +951,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, - sudo_warnx("%s", U_("sesh: killed by a signal")); - break; - default: -- sudo_warnx(U_("sesh: unknown error %d"), rc); -+ sudo_warnx(U_("sesh: unknown error %d"), error); - break; - } - if (ret != 0) -@@ -943,7 +973,7 @@ sudo_edit(struct command_details *command_details) - { - struct command_details saved_command_details; - char **nargv = NULL, **ap, **files = NULL; -- int errors, i, ac, nargc, rc; -+ int errors, i, ac, nargc, ret; - int editor_argc = 0, nfiles = 0; - struct timespec times[2]; - struct tempfile *tf = NULL; -@@ -1038,7 +1068,7 @@ sudo_edit(struct command_details *command_details) - command_details->ngroups = user_details.ngroups; - command_details->groups = user_details.groups; - command_details->argv = nargv; -- rc = run_command(command_details); -+ ret = run_command(command_details); - if (sudo_gettime_real(×[1]) == -1) { - sudo_warn("%s", U_("unable to read the clock")); - goto cleanup; -@@ -1062,14 +1092,14 @@ sudo_edit(struct command_details *command_details) - errors = sudo_edit_copy_tfiles(command_details, tf, nfiles, times); - if (errors) { - /* Preserve the edited temporary files. */ -- rc = W_EXITCODE(1, 0); -+ ret = W_EXITCODE(1, 0); - } - - for (i = 0; i < nfiles; i++) - free(tf[i].tfile); - free(tf); - free(nargv); -- debug_return_int(rc); -+ debug_return_int(ret); - - cleanup: - /* Clean up temp files and return. */ -diff --git a/src/sudo_exec.h b/src/sudo_exec.h -index 39164a785..ec213a6f0 100644 ---- a/src/sudo_exec.h -+++ b/src/sudo_exec.h -@@ -1,7 +1,7 @@ - /* - * SPDX-License-Identifier: ISC - * -- * Copyright (c) 2010-2016 Todd C. Miller -+ * Copyright (c) 2010-2017, 2020-2021 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above -@@ -84,9 +84,11 @@ - */ - struct command_details; - struct command_status; -+struct stat; - - /* copy_file.c */ - int sudo_copy_file(const char *src, int src_fd, off_t src_len, const char *dst, int dst_fd, off_t dst_len); -+bool sudo_check_temp_file(int tfd, const char *tname, uid_t uid, struct stat *sb); - - /* exec.c */ - void exec_cmnd(struct command_details *details, int errfd); diff --git a/backport-Fix-runstatedir-handling-for-distros-that-do-not-support-it.patch b/backport-Fix-runstatedir-handling-for-distros-that-do-not-support-it.patch deleted file mode 100644 index cf5a9ea7bde9bfbedd8f2c1a63e9c26cfb5c88c0..0000000000000000000000000000000000000000 --- a/backport-Fix-runstatedir-handling-for-distros-that-do-not-support-it.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 92e5d81943c890d3ea4b9c140d968563c63b8309 Mon Sep 17 00:00:00 2001 -From: Evan Anderson -Date: Sun, 6 Sep 2020 14:30:54 -0500 -Subject: [PATCH] configure: Fix runstatedir handling for distros that do not - support it - -runstatedir was added in yet-to-be released autoconf 2.70. Some distros -are shipping this addition in their autoconf packages, but others, such as Fedora, -are not. This causes the rundir variable to be set incorrectly if the configure script -is regenerated with an unpatched autoconf since the runstatedir variable set is deleted -after regeneration. This change works around that problem by checking that runstatedir -is non-empty before potentially using it to set the rundir variable ---- - configure | 2 +- - m4/sudo.m4 | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/configure b/configure -index 0f6ceb16c..2e0838e01 100755 ---- a/configure -+++ b/configure -@@ -26718,7 +26718,7 @@ EOF - $as_echo_n "checking for sudo run dir location... " >&6; } - if test -n "$with_rundir"; then - rundir="$with_rundir" --elif test "$runstatedir" != '${localstatedir}/run'; then -+elif test -n "$runstatedir" && test "$runstatedir" != '${localstatedir}/run'; then - rundir="$runstatedir/sudo" - else - # No --with-rundir or --runstatedir specified -diff --git a/m4/sudo.m4 b/m4/sudo.m4 -index a5a972b3c..b3a40b208 100644 ---- a/m4/sudo.m4 -+++ b/m4/sudo.m4 -@@ -120,7 +120,7 @@ dnl - AC_DEFUN([SUDO_RUNDIR], [AC_MSG_CHECKING(for sudo run dir location) - if test -n "$with_rundir"; then - rundir="$with_rundir" --elif test "$runstatedir" != '${localstatedir}/run'; then -+elif test -n "$runstatedir" && test "$runstatedir" != '${localstatedir}/run'; then - rundir="$runstatedir/sudo" - else - # No --with-rundir or --runstatedir specified diff --git a/backport-Fix-some-warnings-from-pvs-studio.patch b/backport-Fix-some-warnings-from-pvs-studio.patch deleted file mode 100644 index 272d6cb5e6bae5c1d8b443ec83a11abc716e98d0..0000000000000000000000000000000000000000 --- a/backport-Fix-some-warnings-from-pvs-studio.patch +++ /dev/null @@ -1,2580 +0,0 @@ -From 961a4afe67c04c86d700695b188809cd984152b2 Mon Sep 17 00:00:00 2001 -From: "Todd C. Miller" -Date: Wed, 12 Aug 2020 13:45:09 -0600 -Subject: [PATCH] Fix some warnings from pvs-studio - ---- - Makefile.in | 2 +- - lib/iolog/iolog_fileio.c | 46 +++++++++++------------- - lib/iolog/iolog_json.c | 26 +++++++------- - lib/util/aix.c | 6 ++-- - lib/util/sudo_debug.c | 1 - - logsrvd/logsrvd.c | 14 ++++---- - logsrvd/sendlog.c | 20 +++++------ - plugins/audit_json/audit_json.c | 4 +-- - plugins/sudoers/auth/aix_auth.c | 2 +- - plugins/sudoers/auth/fwtk.c | 10 +++--- - plugins/sudoers/auth/securid5.c | 22 ++++++------ - plugins/sudoers/bsm_audit.c | 8 ++--- - plugins/sudoers/cvtsudoers.c | 2 +- - plugins/sudoers/cvtsudoers_json.c | 8 ++--- - plugins/sudoers/cvtsudoers_ldif.c | 10 +++--- - plugins/sudoers/env.c | 8 +++-- - plugins/sudoers/iolog.c | 8 ++--- - plugins/sudoers/iolog_client.c | 38 ++++++++++---------- - plugins/sudoers/ldap.c | 9 ++--- - plugins/sudoers/ldap_conf.c | 6 ++-- - plugins/sudoers/linux_audit.c | 4 +-- - plugins/sudoers/logging.c | 2 +- - plugins/sudoers/parse.c | 10 +++--- - plugins/sudoers/policy.c | 10 +++--- - plugins/sudoers/set_perms.c | 10 +++--- - plugins/sudoers/sssd.c | 3 +- - plugins/sudoers/sudoers.c | 19 +++++----- - plugins/sudoers/sudoreplay.c | 32 ++++++++--------- - plugins/sudoers/testsudoers.c | 4 +-- - plugins/sudoers/visudo.c | 20 ++++++----- - src/copy_file.c | 34 +++++++++--------- - src/exec.c | 4 +-- - src/exec_common.c | 2 +- - src/exec_monitor.c | 34 +++++++++--------- - src/exec_nopty.c | 36 +++++++++---------- - src/exec_pty.c | 60 +++++++++++++++---------------- - src/load_plugins.c | 3 +- - src/parse_args.c | 26 ++++++++------ - src/selinux.c | 16 ++++----- - src/sesh.c | 2 +- - src/solaris.c | 4 +-- - src/sudo.c | 11 +++--- - src/sudo_edit.c | 26 +++++++------- - src/tgetpass.c | 16 +++++---- - src/utmp.c | 6 ++-- - 45 files changed, 330 insertions(+), 314 deletions(-) - -diff --git a/Makefile.in b/Makefile.in -index 89d4ab87c..3bf13a6aa 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -101,7 +101,7 @@ SPLINT_OPTS = -D__restrict= -checks - - # Default PVS-studio options when run from the top-level Makefile - PVS_CFG = $(top_builddir)/PVS-Studio.cfg --PVS_IGNORE = 'V707,V011,V002,V536' -+PVS_IGNORE = 'V707,V011,V002,V536,V568' - PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE) - - all: config.status -diff --git a/lib/iolog/iolog_fileio.c b/lib/iolog/iolog_fileio.c -index fa59b21a2..2fa61cbc1 100644 ---- a/lib/iolog/iolog_fileio.c -+++ b/lib/iolog/iolog_fileio.c -@@ -121,23 +121,21 @@ iolog_mkdirs(char *path) - mode_t omask; - struct stat sb; - int dfd; -- bool ok = false, uid_changed = false; -+ bool ok = true, uid_changed = false; - debug_decl(iolog_mkdirs, SUDO_DEBUG_UTIL); - -- if ((dfd = open(path, O_RDONLY|O_NONBLOCK)) != -1) -- ok = true; -- if (!ok && errno == EACCES) { -+ dfd = open(path, O_RDONLY|O_NONBLOCK); -+ if (dfd == -1 && errno == EACCES) { - /* Try again as the I/O log owner (for NFS). */ - if (io_swapids(false)) { -- if ((dfd = open(path, O_RDONLY|O_NONBLOCK)) != -1) -- ok = true; -- if (!io_swapids(true)) -+ dfd = open(path, O_RDONLY|O_NONBLOCK); -+ if (!io_swapids(true)) { - ok = false; -+ goto done; -+ } - } - } -- if (ok && fstat(dfd, &sb) == -1) -- ok = false; -- if (ok) { -+ if (dfd != -1 && fstat(dfd, &sb) != -1) { - if (S_ISDIR(sb.st_mode)) { - if (sb.st_uid != iolog_uid || sb.st_gid != iolog_gid) { - if (fchown(dfd, iolog_uid, iolog_gid) != 0) { -@@ -473,21 +471,19 @@ iolog_nextid(char *iolog_dir, char sessid[7]) - } - - /* Read current seq number (base 36). */ -- if (id == 0) { -- nread = read(fd, buf, sizeof(buf) - 1); -- if (nread != 0) { -- if (nread == -1) { -- goto done; -- } -- if (buf[nread - 1] == '\n') -- nread--; -- buf[nread] = '\0'; -- id = strtoul(buf, &ep, 36); -- if (ep == buf || *ep != '\0' || id >= sessid_max) { -- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, -- "%s: bad sequence number: %s", pathbuf, buf); -- id = 0; -- } -+ nread = read(fd, buf, sizeof(buf) - 1); -+ if (nread != 0) { -+ if (nread == -1) { -+ goto done; -+ } -+ if (buf[nread - 1] == '\n') -+ nread--; -+ buf[nread] = '\0'; -+ id = strtoul(buf, &ep, 36); -+ if (ep == buf || *ep != '\0' || id >= sessid_max) { -+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, -+ "%s: bad sequence number: %s", pathbuf, buf); -+ id = 0; - } - } - id++; -diff --git a/lib/iolog/iolog_json.c b/lib/iolog/iolog_json.c -index 1c52e2c6c..2a8b8d2f1 100644 ---- a/lib/iolog/iolog_json.c -+++ b/lib/iolog/iolog_json.c -@@ -301,14 +301,14 @@ json_parse_string(char **strp) - end++; - } - if (*end != '"') { -- sudo_warnx(U_("missing double quote in name")); -+ sudo_warnx("%s", U_("missing double quote in name")); - debug_return_str(NULL); - } - len = (size_t)(end - src); - - /* Copy string, flattening escaped chars. */ - dst = ret = malloc(len + 1); -- if (ret == NULL) -+ if (dst == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - while (src < end) { - char ch = *src++; -@@ -603,7 +603,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - cp++; - if (stack.depth == 0 || frame->parent == NULL || - frame->parent->type != JSON_OBJECT) { -- sudo_warnx(U_("unmatched close brace")); -+ sudo_warnx("%s", U_("unmatched close brace")); - goto parse_error; - } - frame = stack.frames[--stack.depth]; -@@ -612,7 +612,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - cp++; - if (frame->parent == NULL) { - /* Must have an enclosing object. */ -- sudo_warnx(U_("unexpected array")); -+ sudo_warnx("%s", U_("unexpected array")); - goto parse_error; - } - frame = json_stack_push(&stack, &frame->items, frame, -@@ -625,7 +625,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - cp++; - if (stack.depth == 0 || frame->parent == NULL || - frame->parent->type != JSON_ARRAY) { -- sudo_warnx(U_("unmatched close bracket")); -+ sudo_warnx("%s", U_("unmatched close bracket")); - goto parse_error; - } - frame = stack.frames[--stack.depth]; -@@ -633,7 +633,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - case '"': - if (frame->parent == NULL) { - /* Must have an enclosing object. */ -- sudo_warnx(U_("unexpected string")); -+ sudo_warnx("%s", U_("unexpected string")); - goto parse_error; - } - -@@ -643,7 +643,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - goto parse_error; - /* TODO: allow colon on next line? */ - if (*cp++ != ':') { -- sudo_warnx(U_("missing colon after name")); -+ sudo_warnx("%s", U_("missing colon after name")); - goto parse_error; - } - } else { -@@ -654,7 +654,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - break; - case 't': - if (!expect_value) { -- sudo_warnx(U_("unexpected boolean")); -+ sudo_warnx("%s", U_("unexpected boolean")); - goto parse_error; - } - if (strncmp(cp, "true", sizeof("true") - 1) != 0) -@@ -669,7 +669,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - break; - case 'f': - if (!expect_value) { -- sudo_warnx(U_("unexpected boolean")); -+ sudo_warnx("%s", U_("unexpected boolean")); - goto parse_error; - } - if (strncmp(cp, "false", sizeof("false") - 1) != 0) -@@ -684,7 +684,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - break; - case 'n': - if (!expect_value) { -- sudo_warnx(U_("unexpected boolean")); -+ sudo_warnx("%s", U_("unexpected boolean")); - goto parse_error; - } - if (strncmp(cp, "null", sizeof("null") - 1) != 0) -@@ -700,7 +700,7 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - case '+': case '-': case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': case '8': case '9': - if (!expect_value) { -- sudo_warnx(U_("unexpected number")); -+ sudo_warnx("%s", U_("unexpected number")); - goto parse_error; - } - /* XXX - strtonumx() would be simpler here. */ -@@ -727,9 +727,9 @@ iolog_parse_json(FILE *fp, const char *filename, struct json_object *root) - if (stack.depth != 0) { - frame = stack.frames[stack.depth - 1]; - if (frame->parent == NULL || frame->parent->type == JSON_OBJECT) -- sudo_warnx(U_("unmatched close brace")); -+ sudo_warnx("%s", U_("unmatched close brace")); - else -- sudo_warnx(U_("unmatched close bracket")); -+ sudo_warnx("%s", U_("unmatched close bracket")); - goto parse_error; - } - -diff --git a/lib/util/aix.c b/lib/util/aix.c -index 8d80b512f..495637315 100644 ---- a/lib/util/aix.c -+++ b/lib/util/aix.c -@@ -86,7 +86,7 @@ aix_setlimits(char *user) - debug_decl(aix_setlimits, SUDO_DEBUG_UTIL); - - if (setuserdb(S_READ) != 0) { -- sudo_warn(U_("unable to open userdb")); -+ sudo_warn("%s", U_("unable to open userdb")); - debug_return_int(-1); - } - -@@ -166,7 +166,7 @@ aix_getauthregistry_v1(char *user, char *saved_registry) - char *registry; - - if (setuserdb(S_READ) != 0) { -- sudo_warn(U_("unable to open userdb")); -+ sudo_warn("%s", U_("unable to open userdb")); - goto done; - } - ret = getuserattr(user, S_REGISTRY, ®istry, SEC_CHAR); -@@ -246,7 +246,7 @@ aix_restoreauthdb_v1(void) - debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL); - - if (setauthdb(old_registry, NULL) != 0) { -- sudo_warn(U_("unable to restore registry")); -+ sudo_warn("%s", U_("unable to restore registry")); - ret = -1; - } else { - sudo_debug_printf(SUDO_DEBUG_INFO, -diff --git a/lib/util/sudo_debug.c b/lib/util/sudo_debug.c -index f6a0676e3..deedadfaa 100644 ---- a/lib/util/sudo_debug.c -+++ b/lib/util/sudo_debug.c -@@ -160,7 +160,6 @@ sudo_debug_new_output(struct sudo_debug_instance *instance, - output->filename = strdup(debug_file->debug_file); - if (output->filename == NULL) - goto oom; -- output->fd = -1; - - /* Init per-subsystems settings to -1 since 0 is a valid priority. */ - for (j = 0; j <= instance->max_subsystem; j++) -diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c -index e14e376c1..dcce1dd86 100644 ---- a/logsrvd/logsrvd.c -+++ b/logsrvd/logsrvd.c -@@ -1488,7 +1488,7 @@ new_connection(int sock, bool tls, const struct sockaddr *sa, - sizeof(closure->ipaddr)); - #endif /* HAVE_STRUCT_IN6_ADDR */ - } else { -- sudo_fatal(U_("unable to get remote IP addr")); -+ sudo_fatal("%s", U_("unable to get remote IP addr")); - goto bad; - } - sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, -@@ -1524,7 +1524,7 @@ new_connection(int sock, bool tls, const struct sockaddr *sa, - /* Enable SSL_accept to begin handshake with client. */ - if (sudo_ev_add(evbase, closure->ssl_accept_ev, - logsrvd_conf_get_sock_timeout(), false) == -1) { -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - goto bad; - } - } -@@ -1646,7 +1646,7 @@ register_listener(struct listen_address *addr, struct sudo_event_base *evbase) - if (l->ev == NULL) - sudo_fatal(NULL); - if (sudo_ev_add(evbase, l->ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - TAILQ_INSERT_TAIL(&listeners, l, entries); - - debug_return_bool(true); -@@ -1700,7 +1700,7 @@ server_reload(struct sudo_event_base *base) - if (logsrvd_conf_read(conf_file)) { - /* Re-initialize listeners and TLS context. */ - if (!server_setup(base)) -- sudo_fatalx(U_("unable setup listen socket")); -+ sudo_fatalx("%s", U_("unable setup listen socket")); - - /* Re-initialize debugging. */ - if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) != -1) { -@@ -1746,7 +1746,7 @@ register_signal(int signo, struct sudo_event_base *base) - if (ev == NULL) - sudo_fatal(NULL); - if (sudo_ev_add(base, ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - debug_return; - } -@@ -1895,7 +1895,7 @@ main(int argc, char *argv[]) - sudo_conf_debug_files(getprogname())); - - if (protobuf_c_version_number() < 1003000) -- sudo_fatalx(U_("Protobuf-C version 1.3 or higher required")); -+ sudo_fatalx("%s", U_("Protobuf-C version 1.3 or higher required")); - - while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { - switch (ch) { -@@ -1934,7 +1934,7 @@ main(int argc, char *argv[]) - - /* Initialize listeners and TLS context. */ - if (!server_setup(evbase)) -- sudo_fatalx(U_("unable setup listen socket")); -+ sudo_fatalx("%s", U_("unable setup listen socket")); - - register_signal(SIGHUP, evbase); - register_signal(SIGINT, evbase); -diff --git a/logsrvd/sendlog.c b/logsrvd/sendlog.c -index 1770f9605..8db72c695 100644 ---- a/logsrvd/sendlog.c -+++ b/logsrvd/sendlog.c -@@ -183,7 +183,7 @@ connect_server(const char *host, const char *port) - if (*server_ip == '\0') { - if (inet_ntop(res->ai_family, res->ai_addr, server_ip, - sizeof(server_ip)) == NULL) { -- sudo_warnx(U_("unable to get server IP addr")); -+ sudo_warnx("%s", U_("unable to get server IP addr")); - } - } - break; /* success */ -@@ -1077,7 +1077,7 @@ server_msg_cb(int fd, int what, void *v) - } - - if (what == SUDO_EV_TIMEOUT) { -- sudo_warnx(U_("timeout reading from server")); -+ sudo_warnx("%s", U_("timeout reading from server")); - goto bad; - } - -@@ -1106,7 +1106,7 @@ server_msg_cb(int fd, int what, void *v) - if (!sudo_ev_pending(closure->write_ev, SUDO_EV_WRITE, NULL)) { - /* Enable a temporary write event. */ - if (sudo_ev_add(closure->evbase, closure->write_ev, NULL, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - closure->temporary_write_event = true; -@@ -1219,7 +1219,7 @@ client_msg_cb(int fd, int what, void *v) - } - - if (what == SUDO_EV_TIMEOUT) { -- sudo_warnx(U_("timeout writing to server")); -+ sudo_warnx("%s", U_("timeout writing to server")); - goto bad; - } - -@@ -1438,7 +1438,7 @@ tls_connect_cb(int sock, int what, void *v) - debug_decl(tls_connect_cb, SUDO_DEBUG_UTIL); - - if (what == SUDO_EV_TIMEOUT) { -- sudo_warnx(U_("TLS handshake timeout occurred")); -+ sudo_warnx("%s", U_("TLS handshake timeout occurred")); - goto bad; - } - -@@ -1457,12 +1457,12 @@ tls_connect_cb(int sock, int what, void *v) - if (what != SUDO_EV_READ) { - if (sudo_ev_set(closure->tls_connect_ev, closure->sock, - SUDO_EV_READ, tls_connect_cb, closure) == -1) { -- sudo_warnx(U_("unable to set event")); -+ sudo_warnx("%s", U_("unable to set event")); - goto bad; - } - } - if (sudo_ev_add(evbase, closure->tls_connect_ev, &timeo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - break; -@@ -1472,12 +1472,12 @@ tls_connect_cb(int sock, int what, void *v) - if (what != SUDO_EV_WRITE) { - if (sudo_ev_set(closure->tls_connect_ev, closure->sock, - SUDO_EV_WRITE, tls_connect_cb, closure) == -1) { -- sudo_warnx(U_("unable to set event")); -+ sudo_warnx("%s", U_("unable to set event")); - goto bad; - } - } - if (sudo_ev_add(evbase, closure->tls_connect_ev, &timeo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - break; -@@ -1535,7 +1535,7 @@ tls_setup(struct client_closure *closure) - } - - if (sudo_ev_add(closure->evbase, closure->tls_connect_ev, NULL, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - -diff --git a/plugins/audit_json/audit_json.c b/plugins/audit_json/audit_json.c -index ea8921bec..64adcb738 100644 ---- a/plugins/audit_json/audit_json.c -+++ b/plugins/audit_json/audit_json.c -@@ -413,7 +413,7 @@ audit_write_exit_record(int exit_status, int error) - debug_decl(audit_write_exit_record, SUDO_DEBUG_PLUGIN); - - if (sudo_gettime_real(&now) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto done; - } - -@@ -498,7 +498,7 @@ audit_write_record(const char *audit_str, const char *plugin_name, - debug_decl(audit_write_record, SUDO_DEBUG_PLUGIN); - - if (sudo_gettime_real(&now) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto done; - } - -diff --git a/plugins/sudoers/auth/aix_auth.c b/plugins/sudoers/auth/aix_auth.c -index fed2c46fa..627281160 100644 ---- a/plugins/sudoers/auth/aix_auth.c -+++ b/plugins/sudoers/auth/aix_auth.c -@@ -195,7 +195,7 @@ sudo_aix_change_password(const char *user) - switch (child = sudo_debug_fork()) { - case -1: - /* error */ -- sudo_warn(U_("unable to fork")); -+ sudo_warn("%s", U_("unable to fork")); - break; - case 0: - /* child, run passwd(1) */ -diff --git a/plugins/sudoers/auth/fwtk.c b/plugins/sudoers/auth/fwtk.c -index c9ab06b7f..fa6120581 100644 ---- a/plugins/sudoers/auth/fwtk.c -+++ b/plugins/sudoers/auth/fwtk.c -@@ -51,18 +51,18 @@ sudo_fwtk_init(struct passwd *pw, sudo_auth *auth) - debug_decl(sudo_fwtk_init, SUDOERS_DEBUG_AUTH); - - if ((confp = cfg_read("sudo")) == (Cfg *)-1) { -- sudo_warnx(U_("unable to read fwtk config")); -+ sudo_warnx("%s", U_("unable to read fwtk config")); - debug_return_int(AUTH_FATAL); - } - - if (auth_open(confp)) { -- sudo_warnx(U_("unable to connect to authentication server")); -+ sudo_warnx("%s", U_("unable to connect to authentication server")); - debug_return_int(AUTH_FATAL); - } - - /* Get welcome message from auth server */ - if (auth_recv(resp, sizeof(resp))) { -- sudo_warnx(U_("lost connection to authentication server")); -+ sudo_warnx("%s", U_("lost connection to authentication server")); - debug_return_int(AUTH_FATAL); - } - if (strncmp(resp, "Authsrv ready", 13) != 0) { -@@ -86,7 +86,7 @@ sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_c - (void) snprintf(buf, sizeof(buf), "authorize %s 'sudo'", pw->pw_name); - restart: - if (auth_send(buf) || auth_recv(resp, sizeof(resp))) { -- sudo_warnx(U_("lost connection to authentication server")); -+ sudo_warnx("%s", U_("lost connection to authentication server")); - debug_return_int(AUTH_FATAL); - } - -@@ -118,7 +118,7 @@ sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_c - /* Send the user's response to the server */ - (void) snprintf(buf, sizeof(buf), "response '%s'", pass); - if (auth_send(buf) || auth_recv(resp, sizeof(resp))) { -- sudo_warnx(U_("lost connection to authentication server")); -+ sudo_warnx("%s", U_("lost connection to authentication server")); - error = AUTH_FATAL; - goto done; - } -diff --git a/plugins/sudoers/auth/securid5.c b/plugins/sudoers/auth/securid5.c -index d5804011b..698953fc2 100644 ---- a/plugins/sudoers/auth/securid5.c -+++ b/plugins/sudoers/auth/securid5.c -@@ -69,7 +69,7 @@ sudo_securid_init(struct passwd *pw, sudo_auth *auth) - if (AceInitialize() != SD_FALSE) - debug_return_int(AUTH_SUCCESS); - -- sudo_warnx(U_("failed to initialise the ACE API library")); -+ sudo_warnx("%s", U_("failed to initialise the ACE API library")); - debug_return_int(AUTH_FATAL); - } - -@@ -95,7 +95,7 @@ sudo_securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth) - - /* Re-initialize SecurID every time. */ - if (SD_Init(sd) != ACM_OK) { -- sudo_warnx(U_("unable to contact the SecurID server")); -+ sudo_warnx("%s", U_("unable to contact the SecurID server")); - debug_return_int(AUTH_FATAL); - } - -@@ -104,23 +104,23 @@ sudo_securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth) - - switch (retval) { - case ACM_OK: -- sudo_warnx(U_("User ID locked for SecurID Authentication")); -+ sudo_warnx("%s", U_("User ID locked for SecurID Authentication")); - debug_return_int(AUTH_SUCCESS); - - case ACE_UNDEFINED_USERNAME: -- sudo_warnx(U_("invalid username length for SecurID")); -+ sudo_warnx("%s", U_("invalid username length for SecurID")); - debug_return_int(AUTH_FATAL); - - case ACE_ERR_INVALID_HANDLE: -- sudo_warnx(U_("invalid Authentication Handle for SecurID")); -+ sudo_warnx("%s", U_("invalid Authentication Handle for SecurID")); - debug_return_int(AUTH_FATAL); - - case ACM_ACCESS_DENIED: -- sudo_warnx(U_("SecurID communication failed")); -+ sudo_warnx("%s", U_("SecurID communication failed")); - debug_return_int(AUTH_FATAL); - - default: -- sudo_warnx(U_("unknown SecurID error")); -+ sudo_warnx("%s", U_("unknown SecurID error")); - debug_return_int(AUTH_FATAL); - } - } -@@ -154,17 +154,17 @@ sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_ - break; - - case ACE_UNDEFINED_PASSCODE: -- sudo_warnx(U_("invalid passcode length for SecurID")); -+ sudo_warnx("%s", U_("invalid passcode length for SecurID")); - ret = AUTH_FATAL; - break; - - case ACE_UNDEFINED_USERNAME: -- sudo_warnx(U_("invalid username length for SecurID")); -+ sudo_warnx("%s", U_("invalid username length for SecurID")); - ret = AUTH_FATAL; - break; - - case ACE_ERR_INVALID_HANDLE: -- sudo_warnx(U_("invalid Authentication Handle for SecurID")); -+ sudo_warnx("%s", U_("invalid Authentication Handle for SecurID")); - ret = AUTH_FATAL; - break; - -@@ -207,7 +207,7 @@ then enter the new token code.\n", \ - break; - - default: -- sudo_warnx(U_("unknown SecurID error")); -+ sudo_warnx("%s", U_("unknown SecurID error")); - ret = AUTH_FATAL; - break; - } -diff --git a/plugins/sudoers/bsm_audit.c b/plugins/sudoers/bsm_audit.c -index 60782698f..2867c5f5f 100644 ---- a/plugins/sudoers/bsm_audit.c -+++ b/plugins/sudoers/bsm_audit.c -@@ -120,7 +120,7 @@ bsm_audit_success(char *const exec_args[]) - if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) { - if (errno == AUDIT_NOT_CONFIGURED) - debug_return_int(0); -- sudo_warn(U_("Could not determine audit condition")); -+ sudo_warn("%s", U_("Could not determine audit condition")); - debug_return_int(-1); - } - if (au_cond == AUC_NOAUDIT) -@@ -185,7 +185,7 @@ bsm_audit_success(char *const exec_args[]) - if (au_close(aufd, 1, sudo_audit_event) == -1) - #endif - { -- sudo_warn(U_("unable to commit audit record")); -+ sudo_warn("%s", U_("unable to commit audit record")); - debug_return_int(-1); - } - debug_return_int(0); -@@ -211,7 +211,7 @@ bsm_audit_failure(char *const exec_args[], const char *errmsg) - if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) { - if (errno == AUDIT_NOT_CONFIGURED) - debug_return_int(0); -- sudo_warn(U_("Could not determine audit condition")); -+ sudo_warn("%s", U_("Could not determine audit condition")); - debug_return_int(-1); - } - if (au_cond == AUC_NOAUDIT) -@@ -274,7 +274,7 @@ bsm_audit_failure(char *const exec_args[], const char *errmsg) - if (au_close(aufd, 1, sudo_audit_event) == -1) - #endif - { -- sudo_warn(U_("unable to commit audit record")); -+ sudo_warn("%s", U_("unable to commit audit record")); - debug_return_int(-1); - } - debug_return_int(0); -diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c -index c339556ea..79358121c 100644 ---- a/plugins/sudoers/cvtsudoers.c -+++ b/plugins/sudoers/cvtsudoers.c -@@ -327,7 +327,7 @@ main(int argc, char *argv[]) - - /* Setup defaults data structures. */ - if (!init_defaults()) -- sudo_fatalx(U_("unable to initialize sudoers default values")); -+ sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - - switch (input_format) { - case format_ldif: -diff --git a/plugins/sudoers/cvtsudoers_json.c b/plugins/sudoers/cvtsudoers_json.c -index a846a65cc..93224e7fd 100644 ---- a/plugins/sudoers/cvtsudoers_json.c -+++ b/plugins/sudoers/cvtsudoers_json.c -@@ -637,10 +637,10 @@ print_cmndspec_json(struct json_container *json, - } - if (cs->notbefore != UNSPEC) { - if ((tp = gmtime(&cs->notbefore)) == NULL) { -- sudo_warn(U_("unable to get GMT time")); -+ sudo_warn("%s", U_("unable to get GMT time")); - } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { -- sudo_warnx(U_("unable to format timestamp")); -+ sudo_warnx("%s", U_("unable to format timestamp")); - } else { - value.type = JSON_STRING; - value.u.string = timebuf; -@@ -650,10 +650,10 @@ print_cmndspec_json(struct json_container *json, - } - if (cs->notafter != UNSPEC) { - if ((tp = gmtime(&cs->notafter)) == NULL) { -- sudo_warn(U_("unable to get GMT time")); -+ sudo_warn("%s", U_("unable to get GMT time")); - } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { -- sudo_warnx(U_("unable to format timestamp")); -+ sudo_warnx("%s", U_("unable to format timestamp")); - } else { - value.type = JSON_STRING; - value.u.string = timebuf; -diff --git a/plugins/sudoers/cvtsudoers_ldif.c b/plugins/sudoers/cvtsudoers_ldif.c -index f61f5ff7b..dfab73ad4 100644 ---- a/plugins/sudoers/cvtsudoers_ldif.c -+++ b/plugins/sudoers/cvtsudoers_ldif.c -@@ -342,10 +342,10 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, - /* Print sudoNotBefore and sudoNotAfter attributes */ - if (cs->notbefore != UNSPEC) { - if ((tp = gmtime(&cs->notbefore)) == NULL) { -- sudo_warn(U_("unable to get GMT time")); -+ sudo_warn("%s", U_("unable to get GMT time")); - } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { -- sudo_warnx(U_("unable to format timestamp")); -+ sudo_warnx("%s", U_("unable to format timestamp")); - } else { - print_attribute_ldif(fp, "sudoNotBefore", timebuf); - } -@@ -353,10 +353,10 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, - } - if (cs->notafter != UNSPEC) { - if ((tp = gmtime(&cs->notafter)) == NULL) { -- sudo_warn(U_("unable to get GMT time")); -+ sudo_warn("%s", U_("unable to get GMT time")); - } else { - if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) { -- sudo_warnx(U_("unable to format timestamp")); -+ sudo_warnx("%s", U_("unable to format timestamp")); - } else { - print_attribute_ldif(fp, "sudoNotAfter", timebuf); - } -@@ -672,7 +672,7 @@ convert_sudoers_ldif(struct sudoers_parse_tree *parse_tree, - debug_decl(convert_sudoers_ldif, SUDOERS_DEBUG_UTIL); - - if (conf->sudoers_base == NULL) { -- sudo_fatalx(U_("the SUDOERS_BASE environment variable is not set and the -b option was not specified.")); -+ sudo_fatalx("%s", U_("the SUDOERS_BASE environment variable is not set and the -b option was not specified.")); - } - - if (output_file != NULL && strcmp(output_file, "-") != 0) { -diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c -index 44589d2f1..2cb92a50d 100644 ---- a/plugins/sudoers/env.c -+++ b/plugins/sudoers/env.c -@@ -400,8 +400,10 @@ sudo_putenv(char *str, bool dupcheck, bool overwrite) - ret = sudo_putenv_nodebug(str, dupcheck, overwrite); - if (ret == -1) { - #ifdef ENV_DEBUG -- if (env.envp[env.env_len] != NULL) -- sudo_warnx(U_("sudo_putenv: corrupted envp, length mismatch")); -+ if (env.envp[env.env_len] != NULL) { -+ sudo_warnx("%s", -+ U_("sudo_putenv: corrupted envp, length mismatch")); -+ } - #endif - } - debug_return_int(ret); -@@ -1128,7 +1130,7 @@ rebuild_env(void) - debug_return_bool(true); - - bad: -- sudo_warn(U_("unable to rebuild the environment")); -+ sudo_warn("%s", U_("unable to rebuild the environment")); - debug_return_bool(false); - } - -diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c -index 6e58d39ca..fa8896521 100644 ---- a/plugins/sudoers/iolog.c -+++ b/plugins/sudoers/iolog.c -@@ -628,7 +628,7 @@ sudoers_io_open_remote(struct timespec *now) - /* Connect to log server. */ - if (!log_server_connect(client_closure)) { - /* TODO: support offline logs if server unreachable */ -- sudo_warnx(U_("unable to connect to log server")); -+ sudo_warnx("%s", U_("unable to connect to log server")); - goto done; - } - -@@ -918,7 +918,7 @@ sudoers_io_log_remote(int event, const char *buf, unsigned int len, - ret = client_closure->write_ev->add(client_closure->write_ev, - &iolog_details.server_timeout); - if (ret == -1) -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - } - - done: -@@ -1051,7 +1051,7 @@ sudoers_io_change_winsize_remote(unsigned int lines, unsigned int cols, - ret = client_closure->write_ev->add(client_closure->write_ev, - &iolog_details.server_timeout); - if (ret == -1) -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - } - - debug_return_int(ret); -@@ -1149,7 +1149,7 @@ sudoers_io_suspend_remote(const char *signame, struct timespec *delay, - ret = client_closure->write_ev->add(client_closure->write_ev, - &iolog_details.server_timeout); - if (ret == -1) -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - } - - debug_return_int(ret); -diff --git a/plugins/sudoers/iolog_client.c b/plugins/sudoers/iolog_client.c -index eb73bd832..7cc54f0f4 100644 ---- a/plugins/sudoers/iolog_client.c -+++ b/plugins/sudoers/iolog_client.c -@@ -105,11 +105,11 @@ timed_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, - goto done; - } - if (sudo_ev_add(evbase, connect_event, timo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto done; - } - if (sudo_ev_dispatch(evbase) == -1) { -- sudo_warn(U_("error in event loop")); -+ sudo_warn("%s", U_("error in event loop")); - goto done; - } - if (errnum == 0) -@@ -293,7 +293,7 @@ tls_connect_cb(int sock, int what, void *v) - debug_decl(tls_connect_cb, SUDOERS_DEBUG_UTIL); - - if (what == SUDO_PLUGIN_EV_TIMEOUT) { -- sudo_warnx(U_("TLS handshake timeout occurred")); -+ sudo_warnx("%s", U_("TLS handshake timeout occurred")); - goto bad; - } - -@@ -315,13 +315,13 @@ tls_connect_cb(int sock, int what, void *v) - if (what != SUDO_EV_READ) { - if (sudo_ev_set(closure->tls_connect_ev, sock, - SUDO_EV_READ, tls_connect_cb, closure) == -1) { -- sudo_warnx(U_("unable to set event")); -+ sudo_warnx("%s", U_("unable to set event")); - goto bad; - } - } - if (sudo_ev_add(closure->evbase, closure->tls_connect_ev, - &timeo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - break; -@@ -331,13 +331,13 @@ tls_connect_cb(int sock, int what, void *v) - if (what != SUDO_EV_WRITE) { - if (sudo_ev_set(closure->tls_connect_ev, sock, - SUDO_EV_WRITE, tls_connect_cb, closure) == -1) { -- sudo_warnx(U_("unable to set event")); -+ sudo_warnx("%s", U_("unable to set event")); - goto bad; - } - } - if (sudo_ev_add(closure->evbase, closure->tls_connect_ev, - &timeo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto bad; - } - break; -@@ -383,12 +383,12 @@ tls_timed_connect(SSL *ssl, const char *host, const char *port, - } - - if (sudo_ev_add(closure.evbase, closure.tls_connect_ev, timo, false) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto done; - } - - if (sudo_ev_dispatch(closure.evbase) == -1) { -- sudo_warnx(U_("error in event loop")); -+ sudo_warnx("%s", U_("error in event loop")); - goto done; - } - -@@ -1146,7 +1146,7 @@ client_message_completion(struct client_closure *closure) - /* Enable timeout while waiting for final commit point. */ - if (closure->read_ev->add(closure->read_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - debug_return_bool(false); - } - break; -@@ -1182,7 +1182,7 @@ read_server_hello(struct client_closure *closure) - closure->write_ev->setbase(closure->write_ev, evbase); - if (closure->write_ev->add(closure->write_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto done; - } - -@@ -1190,13 +1190,13 @@ read_server_hello(struct client_closure *closure) - closure->read_ev->setbase(closure->read_ev, evbase); - if (closure->read_ev->add(closure->read_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warnx(U_("unable to add event to queue")); -+ sudo_warnx("%s", U_("unable to add event to queue")); - goto done; - } - - /* Read/write hello messages synchronously. */ - if (sudo_ev_dispatch(evbase) == -1) { -- sudo_warnx(U_("error in event loop")); -+ sudo_warnx("%s", U_("error in event loop")); - goto done; - } - -@@ -1250,7 +1250,7 @@ handle_server_hello(ServerHello *msg, struct client_closure *closure) - */ - closure->read_ev->setbase(closure->read_ev, NULL); - if (closure->read_ev->add(closure->read_ev, NULL) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - debug_return_bool(false); - } - closure->write_ev->setbase(closure->write_ev, NULL); -@@ -1357,7 +1357,7 @@ handle_server_message(uint8_t *buf, size_t len, - if ((ret = fmt_accept_message(closure))) { - if (closure->write_ev->add(closure->write_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - ret = false; - } - } -@@ -1473,7 +1473,7 @@ server_msg_cb(int fd, int what, void *v) - SUDO_PLUGIN_EV_WRITE, NULL)) { - /* Enable a temporary write event. */ - if (closure->write_ev->add(closure->write_ev, NULL) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - goto bad; - } - closure->temporary_write_event = true; -@@ -1755,7 +1755,7 @@ client_close(struct client_closure *closure, int exit_status, int error) - closure->read_ev->setbase(closure->read_ev, evbase); - if (closure->read_ev->add(closure->read_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - goto done; - } - -@@ -1763,7 +1763,7 @@ client_close(struct client_closure *closure, int exit_status, int error) - closure->write_ev->setbase(closure->write_ev, evbase); - if (closure->write_ev->add(closure->write_ev, - &closure->log_details->server_timeout) == -1) { -- sudo_warn(U_("unable to add event to queue")); -+ sudo_warn("%s", U_("unable to add event to queue")); - goto done; - } - -@@ -1771,7 +1771,7 @@ client_close(struct client_closure *closure, int exit_status, int error) - sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, - "flushing buffers and waiting for final commit point"); - if (sudo_ev_dispatch(evbase) == -1 || sudo_ev_got_break(evbase)) { -- sudo_warnx(U_("error in event loop")); -+ sudo_warnx("%s", U_("error in event loop")); - goto done; - } - -diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c -index 448a30d07..d5a647ab4 100644 ---- a/plugins/sudoers/ldap.c -+++ b/plugins/sudoers/ldap.c -@@ -173,7 +173,7 @@ sudo_ldap_join_uri(struct ldap_config_str_list *uri_list) - STAILQ_FOREACH(uri, uri_list, entries) { - if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) { - if (strncasecmp(uri->val, "ldaps://", 8) == 0) { -- sudo_warnx(U_("starttls not supported when using ldaps")); -+ sudo_warnx("%s", U_("starttls not supported when using ldaps")); - ldap_conf.ssl_mode = SUDO_LDAP_SSL; - } - } -@@ -499,13 +499,13 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize) - /* Make sure we have a formatted timestamp for __now__. */ - time(&now); - if ((tp = gmtime(&now)) == NULL) { -- sudo_warn(U_("unable to get GMT time")); -+ sudo_warn("%s", U_("unable to get GMT time")); - goto done; - } - - /* Format the timestamp according to the RFC. */ - if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", tp) == 0) { -- sudo_warnx(U_("unable to format timestamp")); -+ sudo_warnx("%s", U_("unable to format timestamp")); - goto done; - } - -@@ -1691,7 +1691,8 @@ sudo_ldap_open(struct sudo_nss *nss) - } - DPRINTF1("ldap_start_tls_s_np() ok"); - #else -- sudo_warnx(U_("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()")); -+ sudo_warnx("%s", -+ U_("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()")); - #endif /* !HAVE_LDAP_START_TLS_S && !HAVE_LDAP_START_TLS_S_NP */ - } - -diff --git a/plugins/sudoers/ldap_conf.c b/plugins/sudoers/ldap_conf.c -index 5a3bcd1b7..14584d74d 100644 ---- a/plugins/sudoers/ldap_conf.c -+++ b/plugins/sudoers/ldap_conf.c -@@ -197,7 +197,7 @@ sudo_ldap_conf_add_ports(void) - hostbuf[0] = '\0'; - len = snprintf(defport, sizeof(defport), ":%d", ldap_conf.port); - if (len < 0 || len >= ssizeof(defport)) { -- sudo_warnx(U_("sudo_ldap_conf_add_ports: port too large")); -+ sudo_warnx(U_("%s: port too large"), __func__); - debug_return_bool(false); - } - -@@ -284,11 +284,11 @@ sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list) - - if (nldaps != 0) { - if (nldap != 0) { -- sudo_warnx(U_("unable to mix ldap and ldaps URIs")); -+ sudo_warnx("%s", U_("unable to mix ldap and ldaps URIs")); - goto done; - } - if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) -- sudo_warnx(U_("starttls not supported when using ldaps")); -+ sudo_warnx("%s", U_("starttls not supported when using ldaps")); - ldap_conf.ssl_mode = SUDO_LDAP_SSL; - } - free(buf); -diff --git a/plugins/sudoers/linux_audit.c b/plugins/sudoers/linux_audit.c -index 89e5e1021..4f57f4561 100644 ---- a/plugins/sudoers/linux_audit.c -+++ b/plugins/sudoers/linux_audit.c -@@ -55,7 +55,7 @@ linux_audit_open(void) - if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) - au_fd = AUDIT_NOT_CONFIGURED; - else -- sudo_warn(U_("unable to open audit system")); -+ sudo_warn("%s", U_("unable to open audit system")); - } else { - (void)fcntl(au_fd, F_SETFD, FD_CLOEXEC); - } -@@ -98,7 +98,7 @@ linux_audit_command(char *const argv[], int result) - /* Log command, ignoring ECONNREFUSED on error. */ - if (audit_log_user_command(au_fd, AUDIT_USER_CMD, command, NULL, result) <= 0) { - if (errno != ECONNREFUSED) { -- sudo_warn(U_("unable to send audit message")); -+ sudo_warn("%s", U_("unable to send audit message")); - goto done; - } - } -diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c -index 5be2195b5..4a04be0b9 100644 ---- a/plugins/sudoers/logging.c -+++ b/plugins/sudoers/logging.c -@@ -780,7 +780,7 @@ send_mail(const char *fmt, ...) - switch (pid = sudo_debug_fork()) { - case -1: - /* Error. */ -- sudo_warn(U_("unable to fork")); -+ sudo_warn("%s", U_("unable to fork")); - debug_return_bool(false); - break; - case 0: -diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c -index d4f9ca435..e63ac8547 100644 ---- a/plugins/sudoers/parse.c -+++ b/plugins/sudoers/parse.c -@@ -442,9 +442,9 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw, - sudo_lbuf_append(lbuf, _("\nLDAP Role: %s\n"), - priv->ldap_role); - } else { -- sudo_lbuf_append(lbuf, _("\nSudoers entry:\n")); -+ sudo_lbuf_append(lbuf, "%s", _("\nSudoers entry:\n")); - } -- sudo_lbuf_append(lbuf, _(" RunAsUsers: ")); -+ sudo_lbuf_append(lbuf, "%s", _(" RunAsUsers: ")); - if (cs->runasuserlist != NULL) { - TAILQ_FOREACH(m, cs->runasuserlist, entries) { - if (m != TAILQ_FIRST(cs->runasuserlist)) -@@ -459,7 +459,7 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw, - } - sudo_lbuf_append(lbuf, "\n"); - if (cs->runasgrouplist != NULL) { -- sudo_lbuf_append(lbuf, _(" RunAsGroups: ")); -+ sudo_lbuf_append(lbuf, "%s", _(" RunAsGroups: ")); - TAILQ_FOREACH(m, cs->runasgrouplist, entries) { - if (m != TAILQ_FIRST(cs->runasgrouplist)) - sudo_lbuf_append(lbuf, ", "); -@@ -469,7 +469,7 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw, - sudo_lbuf_append(lbuf, "\n"); - } - olen = lbuf->len; -- sudo_lbuf_append(lbuf, _(" Options: ")); -+ sudo_lbuf_append(lbuf, "%s", _(" Options: ")); - TAILQ_FOREACH(d, &priv->defaults, entries) { - sudoers_format_default(lbuf, d); - sudo_lbuf_append(lbuf, ", "); -@@ -519,7 +519,7 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw, - if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm) != 0) - sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf); - } -- sudo_lbuf_append(lbuf, _(" Commands:\n")); -+ sudo_lbuf_append(lbuf, "%s", _(" Commands:\n")); - } - sudo_lbuf_append(lbuf, "\t"); - sudoers_format_member(lbuf, parse_tree, cs->cmnd, "\n\t", -diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c -index 0dd9083b7..b2d28afc2 100644 ---- a/plugins/sudoers/policy.c -+++ b/plugins/sudoers/policy.c -@@ -278,7 +278,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) - if (MATCHES(*cur, "network_addrs=")) { - interfaces_string = *cur + sizeof("network_addrs=") - 1; - if (!set_interfaces(interfaces_string)) { -- sudo_warn(U_("unable to parse network address list")); -+ sudo_warn("%s", U_("unable to parse network address list")); - goto bad; - } - continue; -@@ -423,19 +423,19 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) - - /* User name, user-ID, group-ID and host name must be specified. */ - if (user_name == NULL) { -- sudo_warnx(U_("user name not set by sudo front-end")); -+ sudo_warnx("%s", U_("user name not set by sudo front-end")); - goto bad; - } - if (user_uid == (uid_t)-1) { -- sudo_warnx(U_("user-ID not set by sudo front-end")); -+ sudo_warnx("%s", U_("user-ID not set by sudo front-end")); - goto bad; - } - if (user_gid == (gid_t)-1) { -- sudo_warnx(U_("group-ID not set by sudo front-end")); -+ sudo_warnx("%s", U_("group-ID not set by sudo front-end")); - goto bad; - } - if (user_host == NULL) { -- sudo_warnx(U_("host name not set by sudo front-end")); -+ sudo_warnx("%s", U_("host name not set by sudo front-end")); - goto bad; - } - -diff --git a/plugins/sudoers/set_perms.c b/plugins/sudoers/set_perms.c -index 309f89eea..119ed62b5 100644 ---- a/plugins/sudoers/set_perms.c -+++ b/plugins/sudoers/set_perms.c -@@ -369,7 +369,7 @@ restore_perms(void) - debug_decl(restore_perms, SUDOERS_DEBUG_PERMS); - - if (perm_stack_depth < 2) { -- sudo_warnx(U_("perm stack underflow")); -+ sudo_warnx("%s", U_("perm stack underflow")); - debug_return_bool(true); - } - -@@ -708,7 +708,7 @@ restore_perms(void) - debug_decl(restore_perms, SUDOERS_DEBUG_PERMS); - - if (perm_stack_depth < 2) { -- sudo_warnx(U_("perm stack underflow")); -+ sudo_warnx("%s", U_("perm stack underflow")); - debug_return_bool(true); - } - -@@ -1071,7 +1071,7 @@ restore_perms(void) - debug_decl(restore_perms, SUDOERS_DEBUG_PERMS); - - if (perm_stack_depth < 2) { -- sudo_warnx(U_("perm stack underflow")); -+ sudo_warnx("%s", U_("perm stack underflow")); - debug_return_bool(true); - } - -@@ -1374,7 +1374,7 @@ restore_perms(void) - debug_decl(restore_perms, SUDOERS_DEBUG_PERMS); - - if (perm_stack_depth < 2) { -- sudo_warnx(U_("perm stack underflow")); -+ sudo_warnx("%s", U_("perm stack underflow")); - debug_return_bool(true); - } - -@@ -1539,7 +1539,7 @@ restore_perms(void) - debug_decl(restore_perms, SUDOERS_DEBUG_PERMS); - - if (perm_stack_depth < 2) { -- sudo_warnx(U_("perm stack underflow")); -+ sudo_warnx("%s", U_("perm stack underflow")); - debug_return_bool(true); - } - -diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c -index 605ab4060..dcc80b96e 100644 ---- a/plugins/sudoers/sssd.c -+++ b/plugins/sudoers/sssd.c -@@ -570,7 +570,8 @@ sudo_sss_open(struct sudo_nss *nss) - const char *errstr = sudo_dso_strerror(); - sudo_warnx(U_("unable to load %s: %s"), path, - errstr ? errstr : "unknown error"); -- sudo_warnx(U_("unable to initialize SSS source. Is SSSD installed on your machine?")); -+ sudo_warnx("%s", -+ U_("unable to initialize SSS source. Is SSSD installed on your machine?")); - free(handle); - debug_return_int(EFAULT); - } -diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c -index b74549b65..786c01313 100644 ---- a/plugins/sudoers/sudoers.c -+++ b/plugins/sudoers/sudoers.c -@@ -177,7 +177,7 @@ sudoers_init(void *info, char * const envp[]) - - /* Setup defaults data structures. */ - if (!init_defaults()) { -- sudo_warnx(U_("unable to initialize sudoers default values")); -+ sudo_warnx("%s", U_("unable to initialize sudoers default values")); - debug_return_int(-1); - } - -@@ -217,7 +217,7 @@ sudoers_init(void *info, char * const envp[]) - } - } - if (sources == 0) { -- sudo_warnx(U_("no valid sudoers sources found, quitting")); -+ sudo_warnx("%s", U_("no valid sudoers sources found, quitting")); - goto cleanup; - } - -@@ -293,7 +293,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], - /* Is root even allowed to run sudo? */ - if (user_uid == 0 && !def_root_sudo) { - /* Not an audit event (should it be?). */ -- sudo_warnx(U_("sudoers specifies that root is not allowed to sudo")); -+ sudo_warnx("%s", -+ U_("sudoers specifies that root is not allowed to sudo")); - goto bad; - } - -@@ -354,7 +355,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], - if (!def_closefrom_override) { - audit_failure(NewArgv, - N_("user not allowed to override closefrom limit")); -- sudo_warnx(U_("you are not permitted to use the -C option")); -+ sudo_warnx("%s", U_("you are not permitted to use the -C option")); - goto bad; - } - def_closefrom = user_closefrom; -@@ -432,7 +433,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], - /* Bail if a tty is required and we don't have one. */ - if (def_requiretty && !tty_present()) { - audit_failure(NewArgv, N_("no tty")); -- sudo_warnx(U_("sorry, you must have a tty to run sudo")); -+ sudo_warnx("%s", U_("sorry, you must have a tty to run sudo")); - goto bad; - } - -@@ -522,7 +523,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], - /* If user specified a timeout make sure sudoers allows it. */ - if (!def_user_command_timeouts && user_timeout > 0) { - audit_failure(NewArgv, N_("user not allowed to set a command timeout")); -- sudo_warnx(U_("sorry, you are not allowed set a command timeout")); -+ sudo_warnx("%s", -+ U_("sorry, you are not allowed set a command timeout")); - goto bad; - } - -@@ -531,7 +533,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], - if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) { - audit_failure(NewArgv, - N_("user not allowed to preserve the environment")); -- sudo_warnx(U_("sorry, you are not allowed to preserve the environment")); -+ sudo_warnx("%s", -+ U_("sorry, you are not allowed to preserve the environment")); - goto bad; - } else { - if (!validate_env_vars(sudo_user.env_vars)) -@@ -932,7 +935,7 @@ set_cmnd(void) - if (ISSET(sudo_mode, MODE_RUN) && strcmp(user_base, "sudoedit") == 0) { - CLR(sudo_mode, MODE_RUN); - SET(sudo_mode, MODE_EDIT); -- sudo_warnx(U_("sudoedit doesn't need to be run via sudo")); -+ sudo_warnx("%s", U_("sudoedit doesn't need to be run via sudo")); - user_base = user_cmnd = "sudoedit"; - } - -diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c -index a37c30df9..f83a33d5b 100644 ---- a/plugins/sudoers/sudoreplay.c -+++ b/plugins/sudoers/sudoreplay.c -@@ -508,7 +508,7 @@ getsize_cb(int fd, int what, void *v) - - another: - if (sudo_ev_add(NULL, gc->ev, &gc->timeout, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - done: - debug_return; - } -@@ -555,7 +555,7 @@ xterm_get_size(int *new_lines, int *new_cols) - - /* Read back terminal size response */ - if (sudo_ev_add(evbase, gc.ev, &gc.timeout, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - sudo_ev_dispatch(evbase); - - if (gc.state == GOTSIZE) { -@@ -623,7 +623,7 @@ setup_terminal(struct iolog_info *li, bool interactive, bool resize) - ttyfd = open(_PATH_TTY, O_RDWR); - while (!sudo_term_raw(ttyfd, 1)) { - if (errno != EINTR) -- sudo_fatal(U_("unable to set tty to raw mode")); -+ sudo_fatal("%s", U_("unable to set tty to raw mode")); - kill(getpid(), SIGTTOU); - } - } -@@ -787,7 +787,7 @@ get_timing_record(struct replay_closure *closure) - - /* Schedule the delay event. */ - if (sudo_ev_add(closure->evbase, closure->delay_ev, &timing->delay, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - debug_return_int(0); - } -@@ -899,7 +899,7 @@ delay_cb(int fd, int what, void *v) - if (timing->iol != NULL) { - /* If the stream is open, enable the write event. */ - if (sudo_ev_add(closure->evbase, closure->output_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } else { - /* Not replaying, get the next timing record and continue. */ - next_timing_record(closure); -@@ -989,7 +989,7 @@ replay_closure_alloc(int iolog_dir_fd, const char *iolog_dir, - if (closure->keyboard_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->keyboard_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - closure->output_ev = sudo_ev_alloc(interactive ? ttyfd : STDOUT_FILENO, - SUDO_EV_WRITE, write_output, closure); -@@ -1004,35 +1004,35 @@ replay_closure_alloc(int iolog_dir_fd, const char *iolog_dir, - if (closure->sighup_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->sighup_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - closure->sigint_ev = sudo_ev_alloc(SIGINT, SUDO_EV_SIGNAL, signal_cb, - closure); - if (closure->sigint_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->sigint_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - closure->sigquit_ev = sudo_ev_alloc(SIGQUIT, SUDO_EV_SIGNAL, signal_cb, - closure); - if (closure->sigquit_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->sigquit_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - closure->sigterm_ev = sudo_ev_alloc(SIGTERM, SUDO_EV_SIGNAL, signal_cb, - closure); - if (closure->sigterm_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->sigterm_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - closure->sigtstp_ev = sudo_ev_alloc(SIGTSTP, SUDO_EV_SIGNAL, signal_cb, - closure); - if (closure->sigtstp_ev == NULL) - goto bad; - if (sudo_ev_add(closure->evbase, closure->sigtstp_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - debug_return_ptr(closure); - bad: -@@ -1159,7 +1159,7 @@ write_output(int fd, int what, void *v) - } else { - /* Reschedule event to write remainder. */ - if (sudo_ev_add(NULL, closure->output_ev, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - debug_return; - } -@@ -1245,7 +1245,7 @@ parse_expr(struct search_node_list *head, char *argv[], bool sub_expr) - if (av[0][1] != '\0') - goto bad; - if (!sub_expr) -- sudo_fatalx(U_("unmatched ')' in expression")); -+ sudo_fatalx("%s", U_("unmatched ')' in expression")); - debug_return_int(av - argv + 1); - default: - bad: -@@ -1281,11 +1281,11 @@ parse_expr(struct search_node_list *head, char *argv[], bool sub_expr) - STAILQ_INSERT_TAIL(head, sn, entries); - } - if (sub_expr) -- sudo_fatalx(U_("unmatched '(' in expression")); -+ sudo_fatalx("%s", U_("unmatched '(' in expression")); - if (or) -- sudo_fatalx(U_("illegal trailing \"or\"")); -+ sudo_fatalx("%s", U_("illegal trailing \"or\"")); - if (not) -- sudo_fatalx(U_("illegal trailing \"!\"")); -+ sudo_fatalx("%s", U_("illegal trailing \"!\"")); - - debug_return_int(av - argv); - } -diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c -index f0347b170..effbd60f7 100644 ---- a/plugins/sudoers/testsudoers.c -+++ b/plugins/sudoers/testsudoers.c -@@ -255,7 +255,7 @@ main(int argc, char *argv[]) - - /* Initialize default values. */ - if (!init_defaults()) -- sudo_fatalx(U_("unable to initialize sudoers default values")); -+ sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - - /* Set group_plugin callback. */ - sudo_defs_table[I_GROUP_PLUGIN].callback = cb_group_plugin; -@@ -269,7 +269,7 @@ main(int argc, char *argv[]) - /* Load ip addr/mask for each interface. */ - if (get_net_ifs(&p) > 0) { - if (!set_interfaces(p)) -- sudo_fatal(U_("unable to parse network address list")); -+ sudo_fatal("%s", U_("unable to parse network address list")); - } - - /* Allocate space for data structures in the parser. */ -diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c -index 01aaab8ec..4a1ba6e2a 100644 ---- a/plugins/sudoers/visudo.c -+++ b/plugins/sudoers/visudo.c -@@ -222,8 +222,10 @@ main(int argc, char *argv[]) - - if (export_path != NULL) { - /* Backwards compatibility for the time being. */ -- sudo_warnx(U_("the -x option will be removed in a future release")); -- sudo_warnx(U_("please consider using the cvtsudoers utility instead")); -+ sudo_warnx("%s", -+ U_("the -x option will be removed in a future release")); -+ sudo_warnx("%s", -+ U_("please consider using the cvtsudoers utility instead")); - execlp("cvtsudoers", "cvtsudoers", "-f", "json", "-o", export_path, - sudoers_file, (char *)0); - sudo_fatal(U_("unable to execute %s"), "cvtsudoers"); -@@ -244,7 +246,7 @@ main(int argc, char *argv[]) - - /* Setup defaults data structures. */ - if (!init_defaults()) -- sudo_fatalx(U_("unable to initialize sudoers default values")); -+ sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - - if (checkonly) { - exitcode = check_syntax(sudoers_file, quiet, strict, fflag) ? 0 : 1; -@@ -447,7 +449,7 @@ edit_sudoers(struct sudoersfile *sp, char *editor, int editor_argc, - (void) lseek(sp->fd, (off_t)0, SEEK_SET); - while ((nread = read(sp->fd, buf, sizeof(buf))) > 0) { - if (write(tfd, buf, nread) != nread) -- sudo_fatal(U_("write error")); -+ sudo_fatal("%s", U_("write error")); - lastch = buf[nread - 1]; - } - -@@ -455,7 +457,7 @@ edit_sudoers(struct sudoersfile *sp, char *editor, int editor_argc, - if (lastch != '\n') { - lastch = '\n'; - if (write(tfd, &lastch, 1) != 1) -- sudo_fatal(U_("write error")); -+ sudo_fatal("%s", U_("write error")); - } - } - (void) close(tfd); -@@ -488,13 +490,13 @@ edit_sudoers(struct sudoersfile *sp, char *editor, int editor_argc, - * number of errors during editing (?!?!). - */ - if (sudo_gettime_real(×[0]) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto done; - } - - if (run_command(editor, editor_argv) != -1) { - if (sudo_gettime_real(×[1]) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto done; - } - /* -@@ -600,7 +602,7 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv, - - /* Clean slate for each parse */ - if (!init_defaults()) -- sudo_fatalx(U_("unable to initialize sudoers default values")); -+ sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - init_parser(sp->path, quiet, true); - - /* Parse the sudoers temp file(s) */ -@@ -923,7 +925,7 @@ check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms) - goto done; - } - if (!init_defaults()) -- sudo_fatalx(U_("unable to initialize sudoers default values")); -+ sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - init_parser(sudoers_file, quiet, true); - sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); - if (sudoersparse() && !parse_error) { -diff --git a/src/copy_file.c b/src/copy_file.c -index 9aeb1f92a..a90a3743c 100644 ---- a/src/copy_file.c -+++ b/src/copy_file.c -@@ -113,24 +113,24 @@ sudo_copy_file(const char *src, int src_fd, off_t src_len, const char *dst, - off += nwritten; - } while (nread > off); - } -- if (nread == 0) { -- /* success, read to EOF */ -- if (src_len < dst_len) { -- /* We don't open with O_TRUNC so must truncate manually. */ -- if (ftruncate(dst_fd, src_len) == -1) { -- sudo_debug_printf( -- SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, -- "unable to truncate %s to %lld", dst, (long long)src_len); -- goto write_error; -- } -- } -- debug_return_int(0); -- } else if (nread < 0) { -+ if (nread == -1) { - sudo_warn(U_("unable to read from %s"), src); - debug_return_int(-1); -- } else { --write_error: -- sudo_warn(U_("unable to write to %s"), dst); -- debug_return_int(-1); - } -+ -+ /* Did the file shrink? */ -+ if (src_len < dst_len) { -+ /* We don't open with O_TRUNC so must truncate manually. */ -+ if (ftruncate(dst_fd, src_len) == -1) { -+ sudo_debug_printf( -+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, -+ "unable to truncate %s to %lld", dst, (long long)src_len); -+ goto write_error; -+ } -+ } -+ -+ debug_return_int(0); -+write_error: -+ sudo_warn(U_("unable to write to %s"), dst); -+ debug_return_int(-1); - } -diff --git a/src/exec.c b/src/exec.c -index 606a98396..9c830fd63 100644 ---- a/src/exec.c -+++ b/src/exec.c -@@ -137,7 +137,7 @@ exec_setup(struct command_details *details, int errfd) - flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY|LOGIN_SETUMASK; - } - if (setusercontext(lc, details->pw, details->pw->pw_uid, flags)) { -- sudo_warn(U_("unable to set user context")); -+ sudo_warn("%s", U_("unable to set user context")); - if (details->pw->pw_uid != ROOT_UID) - goto done; - } -@@ -153,7 +153,7 @@ exec_setup(struct command_details *details, int errfd) - - if (ISSET(details->flags, CD_SET_PRIORITY)) { - if (setpriority(PRIO_PROCESS, 0, details->priority) != 0) { -- sudo_warn(U_("unable to set process priority")); -+ sudo_warn("%s", U_("unable to set process priority")); - goto done; - } - } -diff --git a/src/exec_common.c b/src/exec_common.c -index db21d6ed0..909d364ac 100644 ---- a/src/exec_common.c -+++ b/src/exec_common.c -@@ -162,7 +162,7 @@ disable_execute(char *envp[], const char *dso) - (void)priv_set(PRIV_ON, PRIV_INHERITABLE, "PRIV_FILE_DAC_SEARCH", NULL); - if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == 0) - debug_return_ptr(envp); -- sudo_warn(U_("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT")); -+ sudo_warn("%s", U_("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT")); - #endif /* HAVE_PRIV_SET */ - - #ifdef RTLD_PRELOAD_VAR -diff --git a/src/exec_monitor.c b/src/exec_monitor.c -index 3c6d10240..f8a013be4 100644 ---- a/src/exec_monitor.c -+++ b/src/exec_monitor.c -@@ -357,7 +357,7 @@ mon_backchannel_cb(int fd, int what, void *v) - if (n == -1) { - if (errno == EINTR || errno == EAGAIN) - debug_return; -- sudo_warn(U_("error reading from socketpair")); -+ sudo_warn("%s", U_("error reading from socketpair")); - } else { - /* short read or EOF, parent process died? */ - } -@@ -460,7 +460,7 @@ fill_exec_closure_monitor(struct monitor_closure *mc, - if (mc->errpipe_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->errpipe_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - /* Event for forwarded signals via backchannel. */ - mc->backchannel_event = sudo_ev_alloc(backchannel, -@@ -468,7 +468,7 @@ fill_exec_closure_monitor(struct monitor_closure *mc, - if (mc->backchannel_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->backchannel_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - /* Events for local signals. */ - mc->sigint_event = sudo_ev_alloc(SIGINT, -@@ -476,56 +476,56 @@ fill_exec_closure_monitor(struct monitor_closure *mc, - if (mc->sigint_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigint_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigquit_event = sudo_ev_alloc(SIGQUIT, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigquit_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigquit_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigtstp_event = sudo_ev_alloc(SIGTSTP, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigtstp_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigtstp_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigterm_event = sudo_ev_alloc(SIGTERM, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigterm_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigterm_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sighup_event = sudo_ev_alloc(SIGHUP, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sighup_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sighup_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigusr1_event = sudo_ev_alloc(SIGUSR1, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigusr1_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigusr1_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigusr2_event = sudo_ev_alloc(SIGUSR2, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigusr2_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigusr2_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - mc->sigchld_event = sudo_ev_alloc(SIGCHLD, - SUDO_EV_SIGINFO, mon_signal_cb, mc); - if (mc->sigchld_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(mc->evbase, mc->sigchld_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - /* Clear the default event base. */ - sudo_ev_base_setdef(NULL); -@@ -579,7 +579,7 @@ exec_monitor(struct command_details *details, sigset_t *oset, - goto bad; - } - if (pty_make_controlling() == -1) { -- sudo_warn(U_("unable to set controlling tty")); -+ sudo_warn("%s", U_("unable to set controlling tty")); - goto bad; - } - -@@ -587,7 +587,7 @@ exec_monitor(struct command_details *details, sigset_t *oset, - * We use a pipe to get errno if execve(2) fails in the child. - */ - if (pipe2(errpipe, O_CLOEXEC) != 0) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - - /* - * Before forking, wait for the main sudo process to tell us to go. -@@ -595,7 +595,7 @@ exec_monitor(struct command_details *details, sigset_t *oset, - */ - while (recv(backchannel, &cstat, sizeof(cstat), MSG_WAITALL) == -1) { - if (errno != EINTR && errno != EAGAIN) -- sudo_fatal(U_("unable to receive message from parent")); -+ sudo_fatal("%s", U_("unable to receive message from parent")); - } - - #ifdef HAVE_SELINUX -@@ -609,11 +609,11 @@ exec_monitor(struct command_details *details, sigset_t *oset, - mc.cmnd_pid = sudo_debug_fork(); - switch (mc.cmnd_pid) { - case -1: -- sudo_warn(U_("unable to fork")); -+ sudo_warn("%s", U_("unable to fork")); - #ifdef HAVE_SELINUX - if (ISSET(details->flags, CD_RBAC_ENABLED)) { - if (selinux_restore_tty() != 0) -- sudo_warnx(U_("unable to restore tty label")); -+ sudo_warnx("%s", U_("unable to restore tty label")); - } - #endif - goto bad; -@@ -712,7 +712,7 @@ exec_monitor(struct command_details *details, sigset_t *oset, - #ifdef HAVE_SELINUX - if (ISSET(details->flags, CD_RBAC_ENABLED)) { - if (selinux_restore_tty() != 0) -- sudo_warnx(U_("unable to restore tty label")); -+ sudo_warnx("%s", U_("unable to restore tty label")); - } - #endif - sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1); -diff --git a/src/exec_nopty.c b/src/exec_nopty.c -index b03e61e4b..709a1a56f 100644 ---- a/src/exec_nopty.c -+++ b/src/exec_nopty.c -@@ -211,7 +211,7 @@ fill_exec_closure_nopty(struct exec_closure_nopty *ec, - if (ec->errpipe_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->errpipe_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - sudo_debug_printf(SUDO_DEBUG_INFO, "error pipe fd %d\n", errfd); - - /* Events for local signals. */ -@@ -220,77 +220,77 @@ fill_exec_closure_nopty(struct exec_closure_nopty *ec, - if (ec->sigint_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigint_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigquit_event = sudo_ev_alloc(SIGQUIT, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigquit_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigquit_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigtstp_event = sudo_ev_alloc(SIGTSTP, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigtstp_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigtstp_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigterm_event = sudo_ev_alloc(SIGTERM, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigterm_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigterm_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sighup_event = sudo_ev_alloc(SIGHUP, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sighup_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sighup_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigalrm_event = sudo_ev_alloc(SIGALRM, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigalrm_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigalrm_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigpipe_event = sudo_ev_alloc(SIGPIPE, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigpipe_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigpipe_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigusr1_event = sudo_ev_alloc(SIGUSR1, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigusr1_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigusr1_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigusr2_event = sudo_ev_alloc(SIGUSR2, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigusr2_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigusr2_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigchld_event = sudo_ev_alloc(SIGCHLD, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigchld_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigchld_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigcont_event = sudo_ev_alloc(SIGCONT, - SUDO_EV_SIGINFO, signal_cb_nopty, ec); - if (ec->sigcont_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigcont_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - #ifdef SIGINFO - ec->siginfo_event = sudo_ev_alloc(SIGINFO, -@@ -298,7 +298,7 @@ fill_exec_closure_nopty(struct exec_closure_nopty *ec, - if (ec->siginfo_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->siginfo_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - #endif - - /* Set the default event base. */ -@@ -349,13 +349,13 @@ exec_nopty(struct command_details *details, struct command_status *cstat) - * or certain pam modules won't be able to track their state. - */ - if (policy_init_session(details) != true) -- sudo_fatalx(U_("policy plugin failed session initialization")); -+ sudo_fatalx("%s", U_("policy plugin failed session initialization")); - - /* - * We use a pipe to get errno if execve(2) fails in the child. - */ - if (pipe2(errpipe, O_CLOEXEC) != 0) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - - /* - * Block signals until we have our handlers setup in the parent so -@@ -384,7 +384,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat) - ec.cmnd_pid = sudo_debug_fork(); - switch (ec.cmnd_pid) { - case -1: -- sudo_fatal(U_("unable to fork")); -+ sudo_fatal("%s", U_("unable to fork")); - break; - case 0: - /* child */ -@@ -426,7 +426,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat) - * Wait for command to exit, handles signals and the error pipe. - */ - if (sudo_ev_dispatch(ec.evbase) == -1) -- sudo_warn(U_("error in event loop")); -+ sudo_warn("%s", U_("error in event loop")); - if (sudo_ev_got_break(ec.evbase)) { - /* error from callback */ - sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely"); -@@ -438,7 +438,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat) - #ifdef HAVE_SELINUX - if (ISSET(details->flags, CD_RBAC_ENABLED)) { - if (selinux_restore_tty() != 0) -- sudo_warnx(U_("unable to restore tty label")); -+ sudo_warnx("%s", U_("unable to restore tty label")); - } - #endif - -diff --git a/src/exec_pty.c b/src/exec_pty.c -index 1b0863938..fec0b47f4 100644 ---- a/src/exec_pty.c -+++ b/src/exec_pty.c -@@ -149,7 +149,7 @@ pty_setup(struct command_details *details, const char *tty) - - if (!get_pty(&io_fds[SFD_LEADER], &io_fds[SFD_FOLLOWER], - ptyname, sizeof(ptyname), details->euid)) -- sudo_fatal(U_("unable to allocate pty")); -+ sudo_fatal("%s", U_("unable to allocate pty")); - - /* Update tty name in command details (used by SELinux and AIX). */ - details->tty = ptyname; -@@ -690,12 +690,12 @@ read_callback(int fd, int what, void *v) - /* Enable writer now that there is data in the buffer. */ - if (iob->wevent != NULL) { - if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - /* Re-enable reader if buffer is not full. */ - if (iob->len != sizeof(iob->buf)) { - if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - break; - } -@@ -792,14 +792,14 @@ write_callback(int fd, int what, void *v) - /* Re-enable writer if buffer is not empty. */ - if (iob->len > iob->off) { - if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - /* Enable reader if buffer is not full. */ - if (iob->revent != NULL && - (ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) { - if (iob->len != sizeof(iob->buf)) { - if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - } -@@ -896,7 +896,7 @@ send_command_status(struct exec_closure_pty *ec, int type, int val) - TAILQ_INSERT_TAIL(&ec->monitor_messages, msg, entries); - - if (sudo_ev_add(ec->evbase, ec->fwdchannel_event, NULL, true) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - /* Restart event loop to send the command immediately. */ - sudo_ev_loopcontinue(ec->evbase); -@@ -1217,7 +1217,7 @@ fill_exec_closure_pty(struct exec_closure_pty *ec, struct command_status *cstat, - if (ec->backchannel_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->backchannel_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - sudo_debug_printf(SUDO_DEBUG_INFO, "backchannel fd %d\n", backchannel); - - /* Events for local signals. */ -@@ -1226,70 +1226,70 @@ fill_exec_closure_pty(struct exec_closure_pty *ec, struct command_status *cstat, - if (ec->sigint_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigint_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigquit_event = sudo_ev_alloc(SIGQUIT, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigquit_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigquit_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigtstp_event = sudo_ev_alloc(SIGTSTP, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigtstp_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigtstp_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigterm_event = sudo_ev_alloc(SIGTERM, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigterm_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigterm_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sighup_event = sudo_ev_alloc(SIGHUP, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sighup_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sighup_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigalrm_event = sudo_ev_alloc(SIGALRM, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigalrm_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigalrm_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigusr1_event = sudo_ev_alloc(SIGUSR1, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigusr1_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigusr1_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigusr2_event = sudo_ev_alloc(SIGUSR2, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigusr2_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigusr2_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigchld_event = sudo_ev_alloc(SIGCHLD, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigchld_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigchld_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - ec->sigwinch_event = sudo_ev_alloc(SIGWINCH, - SUDO_EV_SIGINFO, signal_cb_pty, ec); - if (ec->sigwinch_event == NULL) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - if (sudo_ev_add(ec->evbase, ec->sigwinch_event, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - - /* The signal forwarding event gets added on demand. */ - ec->fwdchannel_event = sudo_ev_alloc(backchannel, -@@ -1372,7 +1372,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1 || - fcntl(sv[0], F_SETFD, FD_CLOEXEC) == -1 || - fcntl(sv[1], F_SETFD, FD_CLOEXEC) == -1) -- sudo_fatal(U_("unable to create sockets")); -+ sudo_fatal("%s", U_("unable to create sockets")); - - /* - * We don't want to receive SIGTTIN/SIGTTOU. -@@ -1392,7 +1392,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - * or certain pam modules won't be able to track their state. - */ - if (policy_init_session(details) != true) -- sudo_fatalx(U_("policy plugin failed session initialization")); -+ sudo_fatalx("%s", U_("policy plugin failed session initialization")); - - /* - * Child will run the command in the pty, parent will pass data -@@ -1462,7 +1462,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - "stdin not a tty, creating a pipe"); - pipeline = true; - if (pipe2(io_pipe[STDIN_FILENO], O_CLOEXEC) != 0) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1], - log_stdin, &ec, &iobufs); - io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0]; -@@ -1483,7 +1483,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - "stdout not a tty, creating a pipe"); - pipeline = true; - if (pipe2(io_pipe[STDOUT_FILENO], O_CLOEXEC) != 0) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO, - log_stdout, &ec, &iobufs); - io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1]; -@@ -1503,7 +1503,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - sudo_debug_printf(SUDO_DEBUG_INFO, - "stderr not a tty, creating a pipe"); - if (pipe2(io_pipe[STDERR_FILENO], O_CLOEXEC) != 0) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO, - log_stderr, &ec, &iobufs); - io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1]; -@@ -1541,7 +1541,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - ec.monitor_pid = sudo_debug_fork(); - switch (ec.monitor_pid) { - case -1: -- sudo_fatal(U_("unable to fork")); -+ sudo_fatal("%s", U_("unable to fork")); - break; - case 0: - /* child */ -@@ -1584,7 +1584,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - cstat->val = 0; - while (send(sv[0], cstat, sizeof(*cstat), 0) == -1) { - if (errno != EINTR && errno != EAGAIN) -- sudo_fatal(U_("unable to send message to monitor process")); -+ sudo_fatal("%s", U_("unable to send message to monitor process")); - } - - /* Close the other end of the stdin/stdout/stderr pipes and socketpair. */ -@@ -1629,7 +1629,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) - add_io_events(ec.evbase); - do { - if (sudo_ev_dispatch(ec.evbase) == -1) -- sudo_warn(U_("error in event loop")); -+ sudo_warn("%s", U_("error in event loop")); - if (sudo_ev_got_break(ec.evbase)) { - /* error from callback or monitor died */ - sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely"); -@@ -1690,7 +1690,7 @@ add_io_events(struct sudo_event_base *evbase) - "added I/O revent %p, fd %d, events %d", - iob->revent, iob->revent->fd, iob->revent->events); - if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - if (iob->wevent != NULL) { -@@ -1700,7 +1700,7 @@ add_io_events(struct sudo_event_base *evbase) - "added I/O wevent %p, fd %d, events %d", - iob->wevent, iob->wevent->fd, iob->wevent->events); - if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - } -@@ -1745,14 +1745,14 @@ del_io_events(bool nonblocking) - if (iob->revent != NULL && !USERTTY_EVENT(iob->revent)) { - if (iob->len != sizeof(iob->buf)) { - if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - /* Flush any write buffers with data in them. */ - if (iob->wevent != NULL) { - if (iob->len > iob->off) { - if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - } -@@ -1779,7 +1779,7 @@ del_io_events(bool nonblocking) - if (iob->wevent != NULL) { - if (iob->len > iob->off) { - if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) -- sudo_fatal(U_("unable to add event to queue")); -+ sudo_fatal("%s", U_("unable to add event to queue")); - } - } - } -diff --git a/src/load_plugins.c b/src/load_plugins.c -index c636c6abe..578524088 100644 ---- a/src/load_plugins.c -+++ b/src/load_plugins.c -@@ -326,7 +326,8 @@ sudo_load_plugin(struct plugin_container *policy_plugin, - if (!quiet) { - sudo_warnx(U_("ignoring policy plugin \"%s\" in %s, line %d"), - info->symbol_name, _PATH_SUDO_CONF, info->lineno); -- sudo_warnx(U_("only a single policy plugin may be specified")); -+ sudo_warnx("%s", -+ U_("only a single policy plugin may be specified")); - } - goto done; - } -diff --git a/src/parse_args.c b/src/parse_args.c -index d40eacb0b..119cea8e1 100644 ---- a/src/parse_args.c -+++ b/src/parse_args.c -@@ -315,7 +315,8 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - case 'C': - assert(optarg != NULL); - if (sudo_strtonum(optarg, 3, INT_MAX, NULL) == 0) { -- sudo_warnx(U_("the argument to -C must be a number greater than or equal to 3")); -+ sudo_warnx("%s", -+ U_("the argument to -C must be a number greater than or equal to 3")); - usage(); - } - if (sudo_settings[ARG_CLOSEFROM].value != NULL) -@@ -528,11 +529,13 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - - if (ISSET(flags, MODE_LOGIN_SHELL)) { - if (ISSET(flags, MODE_SHELL)) { -- sudo_warnx(U_("you may not specify both the -i and -s options")); -+ sudo_warnx("%s", -+ U_("you may not specify both the -i and -s options")); - usage(); - } - if (ISSET(flags, MODE_PRESERVE_ENV)) { -- sudo_warnx(U_("you may not specify both the -i and -E options")); -+ sudo_warnx("%s", -+ U_("you may not specify both the -i and -E options")); - usage(); - } - SET(flags, MODE_SHELL); -@@ -542,9 +545,10 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - if (mode == MODE_EDIT && - (ISSET(flags, MODE_PRESERVE_ENV) || extra_env.env_len != 0)) { - if (ISSET(mode, MODE_PRESERVE_ENV)) -- sudo_warnx(U_("the -E option is not valid in edit mode")); -+ sudo_warnx("%s", U_("the -E option is not valid in edit mode")); - if (extra_env.env_len != 0) -- sudo_warnx(U_("you may not specify environment variables in edit mode")); -+ sudo_warnx("%s", -+ U_("you may not specify environment variables in edit mode")); - usage(); - } - if ((sudo_settings[ARG_RUNAS_USER].value != NULL || -@@ -553,11 +557,12 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - usage(); - } - if (list_user != NULL && mode != MODE_LIST && mode != MODE_CHECK) { -- sudo_warnx(U_("the -U option may only be used with the -l option")); -+ sudo_warnx("%s", -+ U_("the -U option may only be used with the -l option")); - usage(); - } - if (ISSET(tgetpass_flags, TGP_STDIN) && ISSET(tgetpass_flags, TGP_ASKPASS)) { -- sudo_warnx(U_("the -A and -S options may not be used together")); -+ sudo_warnx("%s", U_("the -A and -S options may not be used together")); - usage(); - } - if ((argc == 0 && mode == MODE_EDIT) || -@@ -650,7 +655,7 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - argv = av; - argc = ac; - #else -- sudo_fatalx(U_("sudoedit is not supported on this platform")); -+ sudo_fatalx("%s", U_("sudoedit is not supported on this platform")); - #endif - } - -@@ -731,7 +736,8 @@ usage_excl(void) - { - debug_decl(usage_excl, SUDO_DEBUG_ARGS); - -- sudo_warnx(U_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified")); -+ sudo_warnx("%s", -+ U_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified")); - usage(); - } - -@@ -752,7 +758,7 @@ help(void) - - display_usage(usage_out); - -- sudo_lbuf_append(&lbuf, _("\nOptions:\n")); -+ sudo_lbuf_append(&lbuf, "%s", _("\nOptions:\n")); - sudo_lbuf_append(&lbuf, " -A, --askpass %s\n", - _("use a helper program for password prompting")); - #ifdef HAVE_BSD_AUTH_H -diff --git a/src/selinux.c b/src/selinux.c -index 5f74c81cc..69d2db606 100644 ---- a/src/selinux.c -+++ b/src/selinux.c -@@ -81,7 +81,7 @@ audit_role_change(const security_context_t old_context, - /* Kernel may not have audit support. */ - if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT - ) -- sudo_fatal(U_("unable to open audit system")); -+ sudo_fatal("%s", U_("unable to open audit system")); - } else { - /* audit role change using the same format as newrole(1) */ - rc = asprintf(&message, "newrole: old-context=%s new-context=%s", -@@ -91,7 +91,7 @@ audit_role_change(const security_context_t old_context, - rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, - message, NULL, NULL, ttyn, result); - if (rc <= 0) -- sudo_warn(U_("unable to send audit message")); -+ sudo_warn("%s", U_("unable to send audit message")); - free(message); - close(au_fd); - } -@@ -199,7 +199,7 @@ relabel_tty(const char *ttyn, int ptyfd) - } - - if (fgetfilecon(se_state.ttyfd, &tty_con) == -1) { -- sudo_warn(U_("unable to get current tty context, not relabeling tty")); -+ sudo_warn("%s", U_("unable to get current tty context, not relabeling tty")); - goto bad; - } - -@@ -211,7 +211,7 @@ relabel_tty(const char *ttyn, int ptyfd) - } - if (security_compute_relabel(se_state.new_context, tty_con, - tclass, &new_tty_con) == -1) { -- sudo_warn(U_("unable to get new tty context, not relabeling tty")); -+ sudo_warn("%s", U_("unable to get new tty context, not relabeling tty")); - goto bad; - } - } -@@ -220,7 +220,7 @@ relabel_tty(const char *ttyn, int ptyfd) - sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tty context %s -> %s", - __func__, tty_con, new_tty_con); - if (fsetfilecon(se_state.ttyfd, new_tty_con) == -1) { -- sudo_warn(U_("unable to set new tty context")); -+ sudo_warn("%s", U_("unable to set new tty context")); - goto bad; - } - } -@@ -336,7 +336,7 @@ get_exec_context(security_context_t old_context, const char *role, const char *t - * its components easily. - */ - if ((context = context_new(old_context)) == NULL) { -- sudo_warn(U_("failed to get new context")); -+ sudo_warn("%s", U_("failed to get new context")); - goto bad; - } - -@@ -393,13 +393,13 @@ selinux_setup(const char *role, const char *type, const char *ttyn, - - /* Store the caller's SID in old_context. */ - if (getprevcon(&se_state.old_context)) { -- sudo_warn(U_("failed to get old context")); -+ sudo_warn("%s", U_("failed to get old context")); - goto done; - } - - se_state.enforcing = security_getenforce(); - if (se_state.enforcing == -1) { -- sudo_warn(U_("unable to determine enforcing mode.")); -+ sudo_warn("%s", U_("unable to determine enforcing mode.")); - goto done; - } - -diff --git a/src/sesh.c b/src/sesh.c -index 5edff5a53..8241f13f1 100644 ---- a/src/sesh.c -+++ b/src/sesh.c -@@ -74,7 +74,7 @@ main(int argc, char *argv[], char *envp[]) - textdomain(PACKAGE_NAME); - - if (argc < 2) -- sudo_fatalx(U_("requires at least one argument")); -+ sudo_fatalx("%s", U_("requires at least one argument")); - - /* Read sudo.conf and initialize the debug subsystem. */ - if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1) -diff --git a/src/solaris.c b/src/solaris.c -index 54b9fbc30..754664f7f 100644 ---- a/src/solaris.c -+++ b/src/solaris.c -@@ -69,14 +69,14 @@ set_project(struct passwd *pw) - case SETPROJ_ERR_TASK: - switch (errno) { - case EAGAIN: -- sudo_warnx(U_("resource control limit has been reached")); -+ sudo_warnx("%s", U_("resource control limit has been reached")); - break; - case ESRCH: - sudo_warnx(U_("user \"%s\" is not a member of project \"%s\""), - pw->pw_name, proj.pj_name); - break; - case EACCES: -- sudo_warnx(U_("the invoking task is final")); -+ sudo_warnx("%s", U_("the invoking task is final")); - break; - default: - sudo_warnx(U_("could not join project \"%s\""), proj.pj_name); -diff --git a/src/sudo.c b/src/sudo.c -index d43fd0698..62096c57c 100644 ---- a/src/sudo.c -+++ b/src/sudo.c -@@ -227,7 +227,7 @@ main(int argc, char *argv[], char *envp[]) - /* Load plugins. */ - if (!sudo_load_plugins(&policy_plugin, &io_plugins, &audit_plugins, - &approval_plugins)) -- sudo_fatalx(U_("fatal error, unable to load plugins")); -+ sudo_fatalx("%s", U_("fatal error, unable to load plugins")); - - /* Allocate event base so plugin can use it. */ - if ((sudo_event_base = sudo_ev_base_alloc()) == NULL) -@@ -272,7 +272,8 @@ main(int argc, char *argv[], char *envp[]) - for (nargv = argv_out, nargc = 0; nargv[nargc] != NULL; nargc++) - continue; - if (nargc == 0) -- sudo_fatalx(U_("plugin did not return a command to execute")); -+ sudo_fatalx("%s", -+ U_("plugin did not return a command to execute")); - - /* Approval plugins run after policy plugin accepts the command. */ - approval_check(settings, user_info, submit_optind, argv, envp, -@@ -597,7 +598,7 @@ get_user_info(struct user_details *ud) - } else { - /* tty may not always be present */ - if (errno != ENOENT) -- sudo_warn(U_("unable to determine tty")); -+ sudo_warn("%s", U_("unable to determine tty")); - } - - cp = sudo_gethostname(); -@@ -927,7 +928,7 @@ set_user_groups(struct command_details *details) - if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) { - if (details->ngroups >= 0) { - if (sudo_setgroups(details->ngroups, details->groups) < 0) { -- sudo_warn(U_("unable to set supplementary group IDs")); -+ sudo_warn("%s", U_("unable to set supplementary group IDs")); - goto done; - } - } -@@ -1092,7 +1093,7 @@ policy_open(struct sudo_settings *settings, char * const user_info[], - usage(); - else { - /* XXX - audit */ -- sudo_fatalx(U_("unable to initialize policy plugin")); -+ sudo_fatalx("%s", U_("unable to initialize policy plugin")); - } - } - -diff --git a/src/sudo_edit.c b/src/sudo_edit.c -index a12870d09..78c407f43 100644 ---- a/src/sudo_edit.c -+++ b/src/sudo_edit.c -@@ -223,7 +223,7 @@ set_tmpdir(struct command_details *command_details) - } - } - if (tdir == NULL) -- sudo_fatalx(U_("no writable temporary directory found")); -+ sudo_fatalx("%s", U_("no writable temporary directory found")); - - len = strlcpy(edit_tmpdir, tdir, sizeof(edit_tmpdir)); - if (len >= sizeof(edit_tmpdir)) { -@@ -348,7 +348,7 @@ sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode) - /* Restore cwd */ - if (odfd != -1) { - if (fchdir(odfd) == -1) -- sudo_fatal(U_("unable to restore current working directory")); -+ sudo_fatal("%s", U_("unable to restore current working directory")); - close(odfd); - } - -@@ -732,7 +732,7 @@ selinux_run_helper(char *argv[], char *envp[]) - child = sudo_debug_fork(); - switch (child) { - case -1: -- sudo_warn(U_("unable to fork")); -+ sudo_warn("%s", U_("unable to fork")); - break; - case 0: - /* child runs sesh in new context */ -@@ -811,11 +811,11 @@ selinux_edit_create_tfiles(struct command_details *command_details, - case SESH_SUCCESS: - break; - case SESH_ERR_BAD_PATHS: -- sudo_fatalx(U_("sesh: internal error: odd number of paths")); -+ sudo_fatalx("%s", U_("sesh: internal error: odd number of paths")); - case SESH_ERR_NO_FILES: -- sudo_fatalx(U_("sesh: unable to create temporary files")); -+ sudo_fatalx("%s", U_("sesh: unable to create temporary files")); - case SESH_ERR_KILLED: -- sudo_fatalx(U_("sesh: killed by a signal")); -+ sudo_fatalx("%s", U_("sesh: killed by a signal")); - default: - sudo_fatalx(U_("sesh: unknown error %d"), rc); - } -@@ -891,13 +891,15 @@ selinux_edit_copy_tfiles(struct command_details *command_details, - ret = 0; - break; - case SESH_ERR_NO_FILES: -- sudo_warnx(U_("unable to copy temporary files back to their original location")); -+ sudo_warnx("%s", -+ U_("unable to copy temporary files back to their original location")); - break; - case SESH_ERR_SOME_FILES: -- sudo_warnx(U_("unable to copy some of the temporary files back to their original location")); -+ sudo_warnx("%s", -+ U_("unable to copy some of the temporary files back to their original location")); - break; - case SESH_ERR_KILLED: -- sudo_warnx(U_("sesh: killed by a signal")); -+ sudo_warnx("%s", U_("sesh: killed by a signal")); - break; - default: - sudo_warnx(U_("sesh: unknown error %d"), rc); -@@ -955,7 +957,7 @@ sudo_edit(struct command_details *command_details) - editor_argc++; - } - if (nfiles == 0) { -- sudo_warnx(U_("plugin error: missing file list for sudoedit")); -+ sudo_warnx("%s", U_("plugin error: missing file list for sudoedit")); - goto cleanup; - } - -@@ -1006,7 +1008,7 @@ sudo_edit(struct command_details *command_details) - * XXX - should run editor with user's context - */ - if (sudo_gettime_real(×[0]) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto cleanup; - } - memcpy(&saved_command_details, command_details, sizeof(struct command_details)); -@@ -1019,7 +1021,7 @@ sudo_edit(struct command_details *command_details) - command_details->argv = nargv; - rc = run_command(command_details); - if (sudo_gettime_real(×[1]) == -1) { -- sudo_warn(U_("unable to read the clock")); -+ sudo_warn("%s", U_("unable to read the clock")); - goto cleanup; - } - -diff --git a/src/tgetpass.c b/src/tgetpass.c -index ad5c94d60..fc4399ef6 100644 ---- a/src/tgetpass.c -+++ b/src/tgetpass.c -@@ -92,13 +92,13 @@ tgetpass_display_error(enum tgetpass_errval errval) - case TGP_ERRVAL_NOERROR: - break; - case TGP_ERRVAL_TIMEOUT: -- sudo_warnx(U_("timed out reading password")); -+ sudo_warnx("%s", U_("timed out reading password")); - break; - case TGP_ERRVAL_NOPASSWORD: -- sudo_warnx(U_("no password was provided")); -+ sudo_warnx("%s", U_("no password was provided")); - break; - case TGP_ERRVAL_READERROR: -- sudo_warn(U_("unable to read password")); -+ sudo_warn("%s", U_("unable to read password")); - break; - } - debug_return; -@@ -137,7 +137,8 @@ tgetpass(const char *prompt, int timeout, int flags, - ttyfd = open(_PATH_TTY, O_RDWR); - if (ttyfd == -1 && !ISSET(flags, TGP_ECHO|TGP_NOECHO_TRY)) { - if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) { -- sudo_warnx(U_("a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper")); -+ sudo_warnx("%s", -+ U_("a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper")); - debug_return_str(NULL); - } - SET(flags, TGP_ASKPASS); -@@ -147,7 +148,8 @@ tgetpass(const char *prompt, int timeout, int flags, - /* If using a helper program to get the password, run it instead. */ - if (ISSET(flags, TGP_ASKPASS)) { - if (askpass == NULL || *askpass == '\0') -- sudo_fatalx(U_("no askpass program specified, try setting SUDO_ASKPASS")); -+ sudo_fatalx("%s", -+ U_("no askpass program specified, try setting SUDO_ASKPASS")); - debug_return_str_masked(sudo_askpass(askpass, prompt)); - } - -@@ -301,11 +303,11 @@ sudo_askpass(const char *askpass, const char *prompt) - (void) sigaction(SIGCHLD, &sa, &savechld); - - if (pipe2(pfd, O_CLOEXEC) == -1) -- sudo_fatal(U_("unable to create pipe")); -+ sudo_fatal("%s", U_("unable to create pipe")); - - child = sudo_debug_fork(); - if (child == -1) -- sudo_fatal(U_("unable to fork")); -+ sudo_fatal("%s", U_("unable to fork")); - - if (child == 0) { - /* child, set stdout to write side of the pipe */ -diff --git a/src/utmp.c b/src/utmp.c -index 4a358f81b..5c3ddbec6 100644 ---- a/src/utmp.c -+++ b/src/utmp.c -@@ -284,12 +284,12 @@ utmp_slot(const char *line, int ttyfd) - * doesn't take an argument. - */ - if ((sfd = dup(STDIN_FILENO)) == -1) -- sudo_fatal(U_("unable to save stdin")); -+ sudo_fatal("%s", U_("unable to save stdin")); - if (dup2(ttyfd, STDIN_FILENO) == -1) -- sudo_fatal(U_("unable to dup2 stdin")); -+ sudo_fatal("%s", U_("unable to dup2 stdin")); - slot = ttyslot(); - if (dup2(sfd, STDIN_FILENO) == -1) -- sudo_fatal(U_("unable to restore stdin")); -+ sudo_fatal("%s", U_("unable to restore stdin")); - close(sfd); - - debug_return_int(slot); diff --git a/sudo-1.9.2.tar.gz b/sudo-1.9.5p2.tar.gz similarity index 34% rename from sudo-1.9.2.tar.gz rename to sudo-1.9.5p2.tar.gz index c59362621e9365df36cf89a3d2be0d62cd3e64ea..f7a59709219e049b2e9d1fee5c3bef9a5e79c053 100644 Binary files a/sudo-1.9.2.tar.gz and b/sudo-1.9.5p2.tar.gz differ diff --git a/sudo.spec b/sudo.spec index 3daf12ef3f99c2451fc6f0aaae417ae4eaf7cc0d..905e6469ea27dff853483e34c141bdf1c7a6bcc2 100644 --- a/sudo.spec +++ b/sudo.spec @@ -1,6 +1,6 @@ Name: sudo -Version: 1.9.2 -Release: 3 +Version: 1.9.5p2 +Release: 1 Summary: Allows restricted root access for specified users License: ISC URL: http://www.courtesan.com/sudo/ @@ -10,16 +10,6 @@ Source1: sudoers Source2: sudo Source3: sudo-i -Patch0: backport-CVE-2021-23239-Fix-potential-directory.patch -Patch1: backport-Fix-some-warnings-from-pvs-studio.patch -Patch2: backport-CVE-2021-23240-Add-security-checks.patch -Patch3: backport-0001-CVE-2021-3156-Reset-valid_flags.patch -Patch4: backport-0002-CVE-2021-3156-Add-sudoedit-flag-checks.patch -Patch5: backport-0003-CVE-2021-3156-Fix-potential-buffer-overflow.patch -Patch6: backport-0004-CVE-2021-3156-Fix-the-memset-offset.patch -Patch7: backport-0005-CVE-2021-3156-Dont-assume-that-argv.patch -Patch8: backport-Fix-runstatedir-handling-for-distros-that-do-not-support-it.patch - Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: pam Recommends: vim-minimal @@ -27,7 +17,7 @@ Requires(post): coreutils BuildRequires: pam-devel groff openldap-devel flex bison automake autoconf libtool BuildRequires: audit-libs-devel libcap-devel libselinux-devel sendmail gettext zlib-devel -BuildRequires: chrpath git +BuildRequires: chrpath git openssl-devel python3-devel %description Sudo is a program designed to allow a sysadmin to give limited root privileges @@ -55,9 +45,8 @@ export CFLAGS="$RPM_OPT_FLAGS -fpie" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" --sbindir=%{_sbindir} \ --libdir=%{_libdir} \ --docdir=%{_pkgdocdir} \ + --enable-openssl \ --disable-root-mailer \ - --disable-log-server \ - --disable-log-client \ --with-logging=syslog \ --with-logfac=authpriv \ --with-pam \ @@ -69,6 +58,7 @@ export CFLAGS="$RPM_OPT_FLAGS -fpie" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" --with-ldap \ --with-selinux \ --with-passprompt="[sudo] password for %p: " \ + --enable-python \ --with-linux-audit \ --with-sssd @@ -123,8 +113,8 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i %attr(0440,root,root) %config(noreplace) /etc/sudoers %attr(0750,root,root) %dir /etc/sudoers.d/ %attr(0644,root,root) %{_tmpfilesdir}/sudo.conf -%attr(0644,root,root) /etc/dnf/protected.d/sudo.conf -%attr(0640,root,root) /etc/sudo.conf +%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/sudo.conf +%attr(0640,root,root) %config(noreplace) /etc/sudo.conf %attr(4111,root,root) %{_bindir}/sudo %attr(0111,root,root) %{_bindir}/sudoreplay %{_bindir}/sudoedit @@ -138,6 +128,10 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i %attr(0644,root,root) %{_libexecdir}/sudo/audit_json.so %attr(0644,root,root) %{_libexecdir}/sudo/sample_approval.so %attr(0644,root,root) %{_libexecdir}/sudo/libsudo_util.so* +%attr(0644,root,root) %{_libexecdir}/sudo/python_plugin.so +%attr(0640,root,root) %config(noreplace) /etc/sudo_logsrvd.conf +%attr(0755,root,root) %{_sbindir}/sudo_logsrvd +%attr(0755,root,root) %{_sbindir}/sudo_sendlog %dir /var/db/sudo %dir /var/db/sudo/lectured %dir %{_libexecdir}/sudo @@ -159,6 +153,9 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i %exclude %{_pkgdocdir}/ChangeLog %changelog +* Wed Jul 7 2021 panxiaohe - 1.9.5p2-1 +- Update to 1.9.5p2 + * Fri Jan 29 2021 zoulin - 1.9.2-3 - Fix runstatedir handling for distros that do not support it