summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/sudo
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/sudo')
-rw-r--r--meta/recipes-extended/sudo/files/CVE-2023-22809.patch113
-rw-r--r--meta/recipes-extended/sudo/sudo.inc4
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2022-43995.patch59
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-1.patch646
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-2.patch26
-rw-r--r--meta/recipes-extended/sudo/sudo_1.8.32.bb4
6 files changed, 851 insertions, 1 deletions
diff --git a/meta/recipes-extended/sudo/files/CVE-2023-22809.patch b/meta/recipes-extended/sudo/files/CVE-2023-22809.patch
new file mode 100644
index 0000000000..6c47eb3e44
--- /dev/null
+++ b/meta/recipes-extended/sudo/files/CVE-2023-22809.patch
@@ -0,0 +1,113 @@
1Backport of:
2
3# HG changeset patch
4# Parent 7275148cad1f8cd3c350026460acc4d6ad349c3a
5sudoedit: do not permit editor arguments to include "--"
6We use "--" to separate the editor and arguments from the files to edit.
7If the editor arguments include "--", sudo can be tricked into allowing
8the user to edit a file not permitted by the security policy.
9Thanks to Matthieu Barjole and Victor Cutillas of Synacktiv
10(https://synacktiv.com) for finding this bug.
11
12CVE: CVE-2023-22809
13Upstream-Staus: Backport [http://archive.ubuntu.com/ubuntu/pool/main/s/sudo/sudo_1.8.31-1ubuntu1.4.debian.tar.xz]
14Signed-off-by: Omkar Patil <omkar.patil@kpit.com>
15
16--- a/plugins/sudoers/editor.c
17+++ b/plugins/sudoers/editor.c
18@@ -56,7 +56,7 @@ resolve_editor(const char *ed, size_t ed
19 const char *cp, *ep, *tmp;
20 const char *edend = ed + edlen;
21 struct stat user_editor_sb;
22- int nargc;
23+ int nargc = 0;
24 debug_decl(resolve_editor, SUDOERS_DEBUG_UTIL)
25
26 /*
27@@ -102,6 +102,21 @@ resolve_editor(const char *ed, size_t ed
28 free(editor_path);
29 while (nargc--)
30 free(nargv[nargc]);
31+ free(nargv);
32+ debug_return_str(NULL);
33+ }
34+
35+ /*
36+ * We use "--" to separate the editor and arguments from the files
37+ * to edit. The editor arguments themselves may not contain "--".
38+ */
39+ if (strcmp(nargv[nargc], "--") == 0) {
40+ sudo_warnx(U_("ignoring editor: %.*s"), (int)edlen, ed);
41+ sudo_warnx("%s", U_("editor arguments may not contain \"--\""));
42+ errno = EINVAL;
43+ free(editor_path);
44+ while (nargc--)
45+ free(nargv[nargc]);
46 free(nargv);
47 debug_return_str(NULL);
48 }
49--- a/plugins/sudoers/sudoers.c
50+++ b/plugins/sudoers/sudoers.c
51@@ -616,20 +616,31 @@ sudoers_policy_main(int argc, char * con
52
53 /* Note: must call audit before uid change. */
54 if (ISSET(sudo_mode, MODE_EDIT)) {
55+ const char *env_editor = NULL;
56 int edit_argc;
57- const char *env_editor;
58
59 free(safe_cmnd);
60 safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
61 &edit_argv, NULL, &env_editor, false);
62 if (safe_cmnd == NULL) {
63- if (errno != ENOENT)
64+ switch (errno) {
65+ case ENOENT:
66+ audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
67+ env_editor ? env_editor : def_editor);
68+ sudo_warnx(U_("%s: command not found"),
69+ env_editor ? env_editor : def_editor);
70+ goto bad;
71+ case EINVAL:
72+ if (def_env_editor && env_editor != NULL) {
73+ /* User tried to do something funny with the editor. */
74+ log_warningx(SLOG_NO_STDERR|SLOG_SEND_MAIL,
75+ "invalid user-specified editor: %s", env_editor);
76+ goto bad;
77+ }
78+ /* FALLTHROUGH */
79+ default:
80 goto done;
81- audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
82- env_editor ? env_editor : def_editor);
83- sudo_warnx(U_("%s: command not found"),
84- env_editor ? env_editor : def_editor);
85- goto bad;
86+ }
87 }
88 if (audit_success(edit_argc, edit_argv) != 0 && !def_ignore_audit_errors)
89 goto done;
90--- a/plugins/sudoers/visudo.c
91+++ b/plugins/sudoers/visudo.c
92@@ -308,7 +308,7 @@ static char *
93 get_editor(int *editor_argc, char ***editor_argv)
94 {
95 char *editor_path = NULL, **whitelist = NULL;
96- const char *env_editor;
97+ const char *env_editor = NULL;
98 static char *files[] = { "+1", "sudoers" };
99 unsigned int whitelist_len = 0;
100 debug_decl(get_editor, SUDOERS_DEBUG_UTIL)
101@@ -342,7 +342,11 @@ get_editor(int *editor_argc, char ***edi
102 if (editor_path == NULL) {
103 if (def_env_editor && env_editor != NULL) {
104 /* We are honoring $EDITOR so this is a fatal error. */
105- sudo_fatalx(U_("specified editor (%s) doesn't exist"), env_editor);
106+ if (errno == ENOENT) {
107+ sudo_warnx(U_("specified editor (%s) doesn't exist"),
108+ env_editor);
109+ }
110+ exit(EXIT_FAILURE);
111 }
112 sudo_fatalx(U_("no editor found (editor path = %s)"), def_editor);
113 }
diff --git a/meta/recipes-extended/sudo/sudo.inc b/meta/recipes-extended/sudo/sudo.inc
index aeedfc1a23..9c7279d25a 100644
--- a/meta/recipes-extended/sudo/sudo.inc
+++ b/meta/recipes-extended/sudo/sudo.inc
@@ -3,7 +3,7 @@ DESCRIPTION = "Sudo (superuser do) allows a system administrator to give certain
3HOMEPAGE = "http://www.sudo.ws" 3HOMEPAGE = "http://www.sudo.ws"
4BUGTRACKER = "http://www.sudo.ws/bugs/" 4BUGTRACKER = "http://www.sudo.ws/bugs/"
5SECTION = "admin" 5SECTION = "admin"
6LICENSE = "ISC & BSD & Zlib" 6LICENSE = "ISC & BSD-3-Clause & BSD-2-Clause & Zlib"
7LIC_FILES_CHKSUM = "file://doc/LICENSE;md5=07966675feaddba70cc812895b248230 \ 7LIC_FILES_CHKSUM = "file://doc/LICENSE;md5=07966675feaddba70cc812895b248230 \
8 file://plugins/sudoers/redblack.c;beginline=1;endline=46;md5=03e35317699ba00b496251e0dfe9f109 \ 8 file://plugins/sudoers/redblack.c;beginline=1;endline=46;md5=03e35317699ba00b496251e0dfe9f109 \
9 file://lib/util/reallocarray.c;beginline=3;endline=15;md5=397dd45c7683e90b9f8bf24638cf03bf \ 9 file://lib/util/reallocarray.c;beginline=3;endline=15;md5=397dd45c7683e90b9f8bf24638cf03bf \
@@ -49,3 +49,5 @@ do_compile_prepend () {
49do_install_prepend (){ 49do_install_prepend (){
50 mkdir -p ${D}/${localstatedir}/lib 50 mkdir -p ${D}/${localstatedir}/lib
51} 51}
52
53CVE_VERSION_SUFFIX = "patch"
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2022-43995.patch b/meta/recipes-extended/sudo/sudo/CVE-2022-43995.patch
new file mode 100644
index 0000000000..1336c7701d
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2022-43995.patch
@@ -0,0 +1,59 @@
1From e1554d7996a59bf69544f3d8dd4ae683027948f9 Mon Sep 17 00:00:00 2001
2From: Hitendra Prajapati <hprajapati@mvista.com>
3Date: Tue, 15 Nov 2022 09:17:18 +0530
4Subject: [PATCH] CVE-2022-43995
5
6Upstream-Status: Backport [https://github.com/sudo-project/sudo/commit/bd209b9f16fcd1270c13db27ae3329c677d48050]
7CVE: CVE-2022-43995
8Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
9
10Potential heap overflow for passwords < 8
11characters. Starting with sudo 1.8.0 the plaintext password buffer is
12dynamically sized so it is not safe to assume that it is at least 9 bytes in
13size.
14Found by Hugo Lefeuvre (University of Manchester) with ConfFuzz.
15---
16 plugins/sudoers/auth/passwd.c | 11 +++++------
17 1 file changed, 5 insertions(+), 6 deletions(-)
18
19diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c
20index 03c7a16..76a7824 100644
21--- a/plugins/sudoers/auth/passwd.c
22+++ b/plugins/sudoers/auth/passwd.c
23@@ -63,7 +63,7 @@ sudo_passwd_init(struct passwd *pw, sudo_auth *auth)
24 int
25 sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
26 {
27- char sav, *epass;
28+ char des_pass[9], *epass;
29 char *pw_epasswd = auth->data;
30 size_t pw_len;
31 int matched = 0;
32@@ -75,12 +75,12 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
33
34 /*
35 * Truncate to 8 chars if standard DES since not all crypt()'s do this.
36- * If this turns out not to be safe we will have to use OS #ifdef's (sigh).
37 */
38- sav = pass[8];
39 pw_len = strlen(pw_epasswd);
40- if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len))
41- pass[8] = '\0';
42+ if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len)) {
43+ strlcpy(des_pass, pass, sizeof(des_pass));
44+ pass = des_pass;
45+ }
46
47 /*
48 * Normal UN*X password check.
49@@ -88,7 +88,6 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
50 * only compare the first DESLEN characters in that case.
51 */
52 epass = (char *) crypt(pass, pw_epasswd);
53- pass[8] = sav;
54 if (epass != NULL) {
55 if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN)
56 matched = !strncmp(pw_epasswd, epass, DESLEN);
57--
582.25.1
59
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-1.patch b/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-1.patch
new file mode 100644
index 0000000000..bc6f8c19a6
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-1.patch
@@ -0,0 +1,646 @@
1Origin: Backport obtained from SUSE. Thanks!
2
3From 334daf92b31b79ce68ed75e2ee14fca265f029ca Mon Sep 17 00:00:00 2001
4From: "Todd C. Miller" <Todd.Miller@sudo.ws>
5Date: Wed, 18 Jan 2023 08:21:34 -0700
6Subject: [PATCH] Escape control characters in log messages and "sudoreplay -l"
7 output. The log message contains user-controlled strings that could include
8 things like terminal control characters. Space characters in the command
9 path are now also escaped.
10
11Command line arguments that contain spaces are surrounded with
12single quotes and any literal single quote or backslash characters
13are escaped with a backslash. This makes it possible to distinguish
14multiple command line arguments from a single argument that contains
15spaces.
16
17Issue found by Matthieu Barjole and Victor Cutillas of Synacktiv
18(https://synacktiv.com).
19
20Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches/CVE-2023-2848x-1.patch?h=ubuntu/focal-security
21Upstream commit https://github.com/sudo-project/sudo/commit/334daf92b31b79ce68ed75e2ee14fca265f029ca]
22CVE: CVE-2023-28486 CVE-2023-28487
23Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
24---
25 doc/sudoers.man.in | 33 +++++++--
26 doc/sudoers.mdoc.in | 28 ++++++--
27 doc/sudoreplay.man.in | 9 ++
28 doc/sudoreplay.mdoc.in | 10 ++
29 include/sudo_compat.h | 6 +
30 include/sudo_lbuf.h | 7 ++
31 lib/util/lbuf.c | 106 +++++++++++++++++++++++++++++++
32 lib/util/util.exp.in | 1
33 plugins/sudoers/logging.c | 145 +++++++++++--------------------------------
34 plugins/sudoers/sudoreplay.c | 44 +++++++++----
35 10 files changed, 257 insertions(+), 132 deletions(-)
36
37--- a/doc/sudoers.man.in
38+++ b/doc/sudoers.man.in
39@@ -4566,6 +4566,19 @@ can log events using either
40 syslog(3)
41 or a simple log file.
42 The log format is almost identical in both cases.
43+Any control characters present in the log data are formatted in octal
44+with a leading
45+\(oq#\(cq
46+character.
47+For example, a horizontal tab is stored as
48+\(oq#011\(cq
49+and an embedded carriage return is stored as
50+\(oq#015\(cq.
51+In addition, space characters in the command path are stored as
52+\(oq#040\(cq.
53+Literal single quotes and backslash characters
54+(\(oq\e\(cq)
55+in command line arguments are escaped with a backslash.
56 .SS "Accepted command log entries"
57 Commands that sudo runs are logged using the following format (split
58 into multiple lines for readability):
59@@ -4646,7 +4659,7 @@ A list of environment variables specifie
60 if specified.
61 .TP 14n
62 command
63-The actual command that was executed.
64+The actual command that was executed, including any command line arguments.
65 .PP
66 Messages are logged using the locale specified by
67 \fIsudoers_locale\fR,
68@@ -4882,17 +4895,21 @@ with a few important differences:
69 1.\&
70 The
71 \fIprogname\fR
72-and
73-\fIhostname\fR
74-fields are not present.
75+field is not present.
76 .TP 5n
77 2.\&
78-If the
79-\fIlog_year\fR
80-option is enabled,
81-the date will also include the year.
82+The
83+\fIhostname\fR
84+is only logged if the
85+\fIlog_host\fR
86+option is enabled.
87 .TP 5n
88 3.\&
89+The date does not include the year unless the
90+\fIlog_year\fR
91+option is enabled.
92+.TP 5n
93+4.\&
94 Lines that are longer than
95 \fIloglinelen\fR
96 characters (80 by default) are word-wrapped and continued on the
97--- a/doc/sudoers.mdoc.in
98+++ b/doc/sudoers.mdoc.in
99@@ -4261,6 +4261,19 @@ can log events using either
100 .Xr syslog 3
101 or a simple log file.
102 The log format is almost identical in both cases.
103+Any control characters present in the log data are formatted in octal
104+with a leading
105+.Ql #
106+character.
107+For example, a horizontal tab is stored as
108+.Ql #011
109+and an embedded carriage return is stored as
110+.Ql #015 .
111+In addition, space characters in the command path are stored as
112+.Ql #040 .
113+Literal single quotes and backslash characters
114+.Pq Ql \e
115+in command line arguments are escaped with a backslash.
116 .Ss Accepted command log entries
117 Commands that sudo runs are logged using the following format (split
118 into multiple lines for readability):
119@@ -4328,7 +4341,7 @@ option is enabled.
120 A list of environment variables specified on the command line,
121 if specified.
122 .It command
123-The actual command that was executed.
124+The actual command that was executed, including any command line arguments.
125 .El
126 .Pp
127 Messages are logged using the locale specified by
128@@ -4550,14 +4563,17 @@ with a few important differences:
129 .It
130 The
131 .Em progname
132-and
133+field is not present.
134+.It
135+The
136 .Em hostname
137-fields are not present.
138+is only logged if the
139+.Em log_host
140+option is enabled.
141 .It
142-If the
143+The date does not include the year unless the
144 .Em log_year
145-option is enabled,
146-the date will also include the year.
147+option is enabled.
148 .It
149 Lines that are longer than
150 .Em loglinelen
151--- a/doc/sudoreplay.man.in
152+++ b/doc/sudoreplay.man.in
153@@ -149,6 +149,15 @@ In this mode,
154 will list available sessions in a format similar to the
155 \fBsudo\fR
156 log file format, sorted by file name (or sequence number).
157+Any control characters present in the log data are formated in octal
158+with a leading
159+\(oq#\(cq
160+character.
161+For example, a horizontal tab is displayed as
162+\(oq#011\(cq
163+and an embedded carriage return is displayed as
164+\(oq#015\(cq.
165+.sp
166 If a
167 \fIsearch expression\fR
168 is specified, it will be used to restrict the IDs that are displayed.
169--- a/doc/sudoreplay.mdoc.in
170+++ b/doc/sudoreplay.mdoc.in
171@@ -142,6 +142,16 @@ In this mode,
172 will list available sessions in a format similar to the
173 .Nm sudo
174 log file format, sorted by file name (or sequence number).
175+Any control characters present in the log data are formatted in octal
176+with a leading
177+.Ql #
178+character.
179+For example, a horizontal tab is displayed as
180+.Ql #011
181+and an embedded carriage return is displayed as
182+.Ql #015 .
183+Space characters in the command name and arguments are also formatted in octal.
184+.Pp
185 If a
186 .Ar search expression
187 is specified, it will be used to restrict the IDs that are displayed.
188--- a/include/sudo_compat.h
189+++ b/include/sudo_compat.h
190@@ -79,6 +79,12 @@
191 # endif
192 #endif
193
194+#ifdef HAVE_FALLTHROUGH_ATTRIBUTE
195+# define FALLTHROUGH __attribute__((__fallthrough__))
196+#else
197+# define FALLTHROUGH do { } while (0)
198+#endif
199+
200 /*
201 * Given the pointer x to the member m of the struct s, return
202 * a pointer to the containing structure.
203--- a/include/sudo_lbuf.h
204+++ b/include/sudo_lbuf.h
205@@ -36,9 +36,15 @@ struct sudo_lbuf {
206
207 typedef int (*sudo_lbuf_output_t)(const char *);
208
209+/* Flags for sudo_lbuf_append_esc() */
210+#define LBUF_ESC_CNTRL 0x01
211+#define LBUF_ESC_BLANK 0x02
212+#define LBUF_ESC_QUOTE 0x04
213+
214 __dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols);
215 __dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf);
216 __dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3);
217+__dso_public bool sudo_lbuf_append_esc_v1(struct sudo_lbuf *lbuf, int flags, const char *fmt, ...) __printflike(3, 4);
218 __dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4);
219 __dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf);
220 __dso_public bool sudo_lbuf_error_v1(struct sudo_lbuf *lbuf);
221@@ -47,6 +53,7 @@ __dso_public void sudo_lbuf_clearerr_v1(
222 #define sudo_lbuf_init(_a, _b, _c, _d, _e) sudo_lbuf_init_v1((_a), (_b), (_c), (_d), (_e))
223 #define sudo_lbuf_destroy(_a) sudo_lbuf_destroy_v1((_a))
224 #define sudo_lbuf_append sudo_lbuf_append_v1
225+#define sudo_lbuf_append_esc sudo_lbuf_append_esc_v1
226 #define sudo_lbuf_append_quoted sudo_lbuf_append_quoted_v1
227 #define sudo_lbuf_print(_a) sudo_lbuf_print_v1((_a))
228 #define sudo_lbuf_error(_a) sudo_lbuf_error_v1((_a))
229--- a/lib/util/lbuf.c
230+++ b/lib/util/lbuf.c
231@@ -93,6 +93,112 @@ sudo_lbuf_expand(struct sudo_lbuf *lbuf,
232 }
233
234 /*
235+ * Escape a character in octal form (#0n) and store it as a string
236+ * in buf, which must have at least 6 bytes available.
237+ * Returns the length of buf, not counting the terminating NUL byte.
238+ */
239+static int
240+escape(unsigned char ch, char *buf)
241+{
242+ const int len = ch < 0100 ? (ch < 010 ? 3 : 4) : 5;
243+
244+ /* Work backwards from the least significant digit to most significant. */
245+ switch (len) {
246+ case 5:
247+ buf[4] = (ch & 7) + '0';
248+ ch >>= 3;
249+ FALLTHROUGH;
250+ case 4:
251+ buf[3] = (ch & 7) + '0';
252+ ch >>= 3;
253+ FALLTHROUGH;
254+ case 3:
255+ buf[2] = (ch & 7) + '0';
256+ buf[1] = '0';
257+ buf[0] = '#';
258+ break;
259+ }
260+ buf[len] = '\0';
261+
262+ return len;
263+}
264+
265+/*
266+ * Parse the format and append strings, only %s and %% escapes are supported.
267+ * Any non-printable characters are escaped in octal as #0nn.
268+ */
269+bool
270+sudo_lbuf_append_esc_v1(struct sudo_lbuf *lbuf, int flags, const char *fmt, ...)
271+{
272+ unsigned int saved_len = lbuf->len;
273+ bool ret = false;
274+ const char *s;
275+ va_list ap;
276+ debug_decl(sudo_lbuf_append_esc, SUDO_DEBUG_UTIL);
277+
278+ if (sudo_lbuf_error(lbuf))
279+ debug_return_bool(false);
280+
281+#define should_escape(ch) \
282+ ((ISSET(flags, LBUF_ESC_CNTRL) && iscntrl((unsigned char)ch)) || \
283+ (ISSET(flags, LBUF_ESC_BLANK) && isblank((unsigned char)ch)))
284+#define should_quote(ch) \
285+ (ISSET(flags, LBUF_ESC_QUOTE) && (ch == '\'' || ch == '\\'))
286+
287+ va_start(ap, fmt);
288+ while (*fmt != '\0') {
289+ if (fmt[0] == '%' && fmt[1] == 's') {
290+ if ((s = va_arg(ap, char *)) == NULL)
291+ s = "(NULL)";
292+ while (*s != '\0') {
293+ if (should_escape(*s)) {
294+ if (!sudo_lbuf_expand(lbuf, sizeof("#0177") - 1))
295+ goto done;
296+ lbuf->len += escape(*s++, lbuf->buf + lbuf->len);
297+ continue;
298+ }
299+ if (should_quote(*s)) {
300+ if (!sudo_lbuf_expand(lbuf, 2))
301+ goto done;
302+ lbuf->buf[lbuf->len++] = '\\';
303+ lbuf->buf[lbuf->len++] = *s++;
304+ continue;
305+ }
306+ if (!sudo_lbuf_expand(lbuf, 1))
307+ goto done;
308+ lbuf->buf[lbuf->len++] = *s++;
309+ }
310+ fmt += 2;
311+ continue;
312+ }
313+ if (should_escape(*fmt)) {
314+ if (!sudo_lbuf_expand(lbuf, sizeof("#0177") - 1))
315+ goto done;
316+ if (*fmt == '\'') {
317+ lbuf->buf[lbuf->len++] = '\\';
318+ lbuf->buf[lbuf->len++] = *fmt++;
319+ } else {
320+ lbuf->len += escape(*fmt++, lbuf->buf + lbuf->len);
321+ }
322+ continue;
323+ }
324+ if (!sudo_lbuf_expand(lbuf, 1))
325+ goto done;
326+ lbuf->buf[lbuf->len++] = *fmt++;
327+ }
328+ ret = true;
329+
330+done:
331+ if (!ret)
332+ lbuf->len = saved_len;
333+ if (lbuf->size != 0)
334+ lbuf->buf[lbuf->len] = '\0';
335+ va_end(ap);
336+
337+ debug_return_bool(ret);
338+}
339+
340+/*
341 * Parse the format and append strings, only %s and %% escapes are supported.
342 * Any characters in set are quoted with a backslash.
343 */
344--- a/lib/util/util.exp.in
345+++ b/lib/util/util.exp.in
346@@ -79,6 +79,7 @@ sudo_gethostname_v1
347 sudo_gettime_awake_v1
348 sudo_gettime_mono_v1
349 sudo_gettime_real_v1
350+sudo_lbuf_append_esc_v1
351 sudo_lbuf_append_quoted_v1
352 sudo_lbuf_append_v1
353 sudo_lbuf_clearerr_v1
354--- a/plugins/sudoers/logging.c
355+++ b/plugins/sudoers/logging.c
356@@ -58,6 +58,7 @@
357 #include <syslog.h>
358
359 #include "sudoers.h"
360+#include "sudo_lbuf.h"
361
362 #ifndef HAVE_GETADDRINFO
363 # include "compat/getaddrinfo.h"
364@@ -940,14 +941,6 @@ should_mail(int status)
365 (def_mail_no_perms && !ISSET(status, VALIDATE_SUCCESS)));
366 }
367
368-#define LL_TTY_STR "TTY="
369-#define LL_CWD_STR "PWD=" /* XXX - should be CWD= */
370-#define LL_USER_STR "USER="
371-#define LL_GROUP_STR "GROUP="
372-#define LL_ENV_STR "ENV="
373-#define LL_CMND_STR "COMMAND="
374-#define LL_TSID_STR "TSID="
375-
376 #define IS_SESSID(s) ( \
377 isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
378 (s)[2] == '/' && \
379@@ -962,14 +955,16 @@ should_mail(int status)
380 static char *
381 new_logline(const char *message, const char *errstr)
382 {
383- char *line = NULL, *evstr = NULL;
384 #ifndef SUDOERS_NO_SEQ
385 char sessid[7];
386 #endif
387 const char *tsid = NULL;
388- size_t len = 0;
389+ struct sudo_lbuf lbuf;
390+ int i;
391 debug_decl(new_logline, SUDOERS_DEBUG_LOGGING)
392
393+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
394+
395 #ifndef SUDOERS_NO_SEQ
396 /* A TSID may be a sudoers-style session ID or a free-form string. */
397 if (sudo_user.iolog_file != NULL) {
398@@ -989,119 +984,55 @@ new_logline(const char *message, const c
399 #endif
400
401 /*
402- * Compute line length
403+ * Format the log line as an lbuf, escaping control characters in
404+ * octal form (#0nn). Error checking (ENOMEM) is done at the end.
405 */
406- if (message != NULL)
407- len += strlen(message) + 3;
408- if (errstr != NULL)
409- len += strlen(errstr) + 3;
410- len += sizeof(LL_TTY_STR) + 2 + strlen(user_tty);
411- len += sizeof(LL_CWD_STR) + 2 + strlen(user_cwd);
412- if (runas_pw != NULL)
413- len += sizeof(LL_USER_STR) + 2 + strlen(runas_pw->pw_name);
414- if (runas_gr != NULL)
415- len += sizeof(LL_GROUP_STR) + 2 + strlen(runas_gr->gr_name);
416- if (tsid != NULL)
417- len += sizeof(LL_TSID_STR) + 2 + strlen(tsid);
418- if (sudo_user.env_vars != NULL) {
419- size_t evlen = 0;
420- char * const *ep;
421-
422- for (ep = sudo_user.env_vars; *ep != NULL; ep++)
423- evlen += strlen(*ep) + 1;
424- if (evlen != 0) {
425- if ((evstr = malloc(evlen)) == NULL)
426- goto oom;
427- evstr[0] = '\0';
428- for (ep = sudo_user.env_vars; *ep != NULL; ep++) {
429- strlcat(evstr, *ep, evlen);
430- strlcat(evstr, " ", evlen); /* NOTE: last one will fail */
431- }
432- len += sizeof(LL_ENV_STR) + 2 + evlen;
433- }
434- }
435- if (user_cmnd != NULL) {
436- /* Note: we log "sudo -l command arg ..." as "list command arg ..." */
437- len += sizeof(LL_CMND_STR) - 1 + strlen(user_cmnd);
438- if (ISSET(sudo_mode, MODE_CHECK))
439- len += sizeof("list ") - 1;
440- if (user_args != NULL)
441- len += strlen(user_args) + 1;
442- }
443-
444- /*
445- * Allocate and build up the line.
446- */
447- if ((line = malloc(++len)) == NULL)
448- goto oom;
449- line[0] = '\0';
450
451 if (message != NULL) {
452- if (strlcat(line, message, len) >= len ||
453- strlcat(line, errstr ? " : " : " ; ", len) >= len)
454- goto toobig;
455+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s%s", message,
456+ errstr ? " : " : " ; ");
457 }
458 if (errstr != NULL) {
459- if (strlcat(line, errstr, len) >= len ||
460- strlcat(line, " ; ", len) >= len)
461- goto toobig;
462- }
463- if (strlcat(line, LL_TTY_STR, len) >= len ||
464- strlcat(line, user_tty, len) >= len ||
465- strlcat(line, " ; ", len) >= len)
466- goto toobig;
467- if (strlcat(line, LL_CWD_STR, len) >= len ||
468- strlcat(line, user_cwd, len) >= len ||
469- strlcat(line, " ; ", len) >= len)
470- goto toobig;
471+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s ; ", errstr);
472+ }
473+ if (user_tty != NULL) {
474+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ", user_tty);
475+ }
476+ if (user_cwd != NULL) {
477+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "PWD=%s ; ", user_cwd);
478+ }
479 if (runas_pw != NULL) {
480- if (strlcat(line, LL_USER_STR, len) >= len ||
481- strlcat(line, runas_pw->pw_name, len) >= len ||
482- strlcat(line, " ; ", len) >= len)
483- goto toobig;
484+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "USER=%s ; ",
485+ runas_pw->pw_name);
486 }
487 if (runas_gr != NULL) {
488- if (strlcat(line, LL_GROUP_STR, len) >= len ||
489- strlcat(line, runas_gr->gr_name, len) >= len ||
490- strlcat(line, " ; ", len) >= len)
491- goto toobig;
492+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ",
493+ runas_gr->gr_name);
494 }
495 if (tsid != NULL) {
496- if (strlcat(line, LL_TSID_STR, len) >= len ||
497- strlcat(line, tsid, len) >= len ||
498- strlcat(line, " ; ", len) >= len)
499- goto toobig;
500- }
501- if (evstr != NULL) {
502- if (strlcat(line, LL_ENV_STR, len) >= len ||
503- strlcat(line, evstr, len) >= len ||
504- strlcat(line, " ; ", len) >= len)
505- goto toobig;
506- free(evstr);
507- evstr = NULL;
508+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TSID=%s ; ", tsid);
509+ }
510+ if (sudo_user.env_vars != NULL) {
511+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "ENV=%s", sudo_user.env_vars[0]);
512+ for (i = 1; sudo_user.env_vars[i] != NULL; i++) {
513+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " %s",
514+ sudo_user.env_vars[i]);
515+ }
516 }
517 if (user_cmnd != NULL) {
518- if (strlcat(line, LL_CMND_STR, len) >= len)
519- goto toobig;
520- if (ISSET(sudo_mode, MODE_CHECK) && strlcat(line, "list ", len) >= len)
521- goto toobig;
522- if (strlcat(line, user_cmnd, len) >= len)
523- goto toobig;
524+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK,
525+ "COMMAND=%s", user_cmnd);
526 if (user_args != NULL) {
527- if (strlcat(line, " ", len) >= len ||
528- strlcat(line, user_args, len) >= len)
529- goto toobig;
530+ sudo_lbuf_append_esc(&lbuf,
531+ LBUF_ESC_CNTRL|LBUF_ESC_QUOTE,
532+ " %s", user_args);
533 }
534 }
535
536- debug_return_str(line);
537-oom:
538- free(evstr);
539+ if (!sudo_lbuf_error(&lbuf))
540+ debug_return_str(lbuf.buf);
541+
542+ sudo_lbuf_destroy(&lbuf);
543 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
544 debug_return_str(NULL);
545-toobig:
546- free(evstr);
547- free(line);
548- sudo_warnx(U_("internal error, %s overflow"), __func__);
549- debug_return_str(NULL);
550 }
551--- a/plugins/sudoers/sudoreplay.c
552+++ b/plugins/sudoers/sudoreplay.c
553@@ -71,6 +71,7 @@
554 #include "sudo_conf.h"
555 #include "sudo_debug.h"
556 #include "sudo_event.h"
557+#include "sudo_lbuf.h"
558 #include "sudo_util.h"
559
560 #ifdef HAVE_GETOPT_LONG
561@@ -1353,7 +1354,8 @@ match_expr(struct search_node_list *head
562 }
563
564 static int
565-list_session(char *logfile, regex_t *re, const char *user, const char *tty)
566+list_session(struct sudo_lbuf *lbuf, char *logfile, regex_t *re,
567+ const char *user, const char *tty)
568 {
569 char idbuf[7], *idstr, *cp;
570 const char *timestr;
571@@ -1386,16 +1388,32 @@ list_session(char *logfile, regex_t *re,
572 }
573 /* XXX - print rows + cols? */
574 timestr = get_timestr(li->tstamp, 1);
575- printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ",
576- timestr ? timestr : "invalid date",
577- li->user, li->tty, li->cwd, li->runas_user);
578- if (li->runas_group)
579- printf("GROUP=%s ; ", li->runas_group);
580- printf("TSID=%s ; COMMAND=%s\n", idstr, li->cmd);
581-
582- ret = 0;
583-
584+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s : %s : ",
585+ timestr ? timestr : "invalid date", li->user);
586+ if (li->tty != NULL) {
587+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ",
588+ li->tty);
589+ }
590+ if (li->cwd != NULL) {
591+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CWD=%s ; ",
592+ li->cwd);
593+ }
594+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "USER=%s ; ", li->runas_user);
595+ if (li->runas_group != NULL) {
596+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ",
597+ li->runas_group);
598+ }
599+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TSID=%s ; ", idstr);
600+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "COMMAND=%s",
601+ li->cmd);
602+
603+ if (!sudo_lbuf_error(lbuf)) {
604+ puts(lbuf->buf);
605+ ret = 0;
606+ }
607 done:
608+ lbuf->error = 0;
609+ lbuf->len = 0;
610 free_log_info(li);
611 debug_return_int(ret);
612 }
613@@ -1415,6 +1433,7 @@ find_sessions(const char *dir, regex_t *
614 DIR *d;
615 struct dirent *dp;
616 struct stat sb;
617+ struct sudo_lbuf lbuf;
618 size_t sdlen, sessions_len = 0, sessions_size = 0;
619 unsigned int i;
620 int len;
621@@ -1426,6 +1445,8 @@ find_sessions(const char *dir, regex_t *
622 #endif
623 debug_decl(find_sessions, SUDO_DEBUG_UTIL)
624
625+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
626+
627 d = opendir(dir);
628 if (d == NULL)
629 sudo_fatal(U_("unable to open %s"), dir);
630@@ -1485,7 +1506,7 @@ find_sessions(const char *dir, regex_t *
631
632 /* Check for dir with a log file. */
633 if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
634- list_session(pathbuf, re, user, tty);
635+ list_session(&lbuf, pathbuf, re, user, tty);
636 } else {
637 /* Strip off "/log" and recurse if a dir. */
638 pathbuf[sdlen + len - 4] = '\0';
639@@ -1496,6 +1517,7 @@ find_sessions(const char *dir, regex_t *
640 }
641 free(sessions);
642 }
643+ sudo_lbuf_destroy(&lbuf);
644
645 debug_return_int(0);
646 }
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-2.patch b/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-2.patch
new file mode 100644
index 0000000000..d021873b70
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2023-28486_CVE-2023-28487-2.patch
@@ -0,0 +1,26 @@
1Backport of:
2
3From 12648b4e0a8cf486480442efd52f0e0b6cab6e8b Mon Sep 17 00:00:00 2001
4From: "Todd C. Miller" <Todd.Miller@sudo.ws>
5Date: Mon, 13 Mar 2023 08:04:32 -0600
6Subject: [PATCH] Add missing " ; " separator between environment variables and
7 command. This is a regression introduced in sudo 1.9.13. GitHub issue #254.
8
9Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches/CVE-2023-2848x-2.patch?h=ubuntu/focal-security
10Upstream commit https://github.com/sudo-project/sudo/commit/12648b4e0a8cf486480442efd52f0e0b6cab6e8b]
11CVE: CVE-2023-28486 CVE-2023-28487
12Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
13---
14 lib/eventlog/eventlog.c | 1 +
15 1 file changed, 1 insertion(+)
16
17--- a/plugins/sudoers/logging.c
18+++ b/plugins/sudoers/logging.c
19@@ -1018,6 +1018,7 @@ new_logline(const char *message, const c
20 sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " %s",
21 sudo_user.env_vars[i]);
22 }
23+ sudo_lbuf_append(&lbuf, " ; ");
24 }
25 if (user_cmnd != NULL) {
26 sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK,
diff --git a/meta/recipes-extended/sudo/sudo_1.8.32.bb b/meta/recipes-extended/sudo/sudo_1.8.32.bb
index 8d16ec2538..e35bbfa789 100644
--- a/meta/recipes-extended/sudo/sudo_1.8.32.bb
+++ b/meta/recipes-extended/sudo/sudo_1.8.32.bb
@@ -4,6 +4,10 @@ SRC_URI = "https://www.sudo.ws/dist/sudo-${PV}.tar.gz \
4 ${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \ 4 ${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
5 file://0001-Include-sys-types.h-for-id_t-definition.patch \ 5 file://0001-Include-sys-types.h-for-id_t-definition.patch \
6 file://0001-Fix-includes-when-building-with-musl.patch \ 6 file://0001-Fix-includes-when-building-with-musl.patch \
7 file://CVE-2022-43995.patch \
8 file://CVE-2023-22809.patch \
9 file://CVE-2023-28486_CVE-2023-28487-1.patch \
10 file://CVE-2023-28486_CVE-2023-28487-2.patch \
7 " 11 "
8 12
9PAM_SRC_URI = "file://sudo.pam" 13PAM_SRC_URI = "file://sudo.pam"