diff options
| author | Vijay Anusuri <vanusuri@mvista.com> | 2023-04-21 08:49:35 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2023-05-03 04:09:42 -1000 |
| commit | 799673e3f48db669446c2c7755724a2801d83693 (patch) | |
| tree | 3c1ed034b283a712980d97bda4b34f638342cd10 | |
| parent | 6fd646cdb1a41e5d62c9d377706482b802d521f8 (diff) | |
| download | poky-799673e3f48db669446c2c7755724a2801d83693.tar.gz | |
sudo: Security fix for CVE-2023-28486 and CVE-2023-28487
import patches from ubuntu to fix
CVE-2023-28486
CVE-2023-28487
Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/focal-security
Upstream commit https://github.com/sudo-project/sudo/commit/334daf92b31b79ce68ed75e2ee14fca265f029ca & https://github.com/sudo-project/sudo/commit/12648b4e0a8cf486480442efd52f0e0b6cab6e8b]
(From OE-Core rev: 4870543273bef9831c075ee0bce108c54355a92f)
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
3 files changed, 674 insertions, 0 deletions
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 @@ | |||
| 1 | Origin: Backport obtained from SUSE. Thanks! | ||
| 2 | |||
| 3 | From 334daf92b31b79ce68ed75e2ee14fca265f029ca Mon Sep 17 00:00:00 2001 | ||
| 4 | From: "Todd C. Miller" <Todd.Miller@sudo.ws> | ||
| 5 | Date: Wed, 18 Jan 2023 08:21:34 -0700 | ||
| 6 | Subject: [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 | |||
| 11 | Command line arguments that contain spaces are surrounded with | ||
| 12 | single quotes and any literal single quote or backslash characters | ||
| 13 | are escaped with a backslash. This makes it possible to distinguish | ||
| 14 | multiple command line arguments from a single argument that contains | ||
| 15 | spaces. | ||
| 16 | |||
| 17 | Issue found by Matthieu Barjole and Victor Cutillas of Synacktiv | ||
| 18 | (https://synacktiv.com). | ||
| 19 | |||
| 20 | Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches/CVE-2023-2848x-1.patch?h=ubuntu/focal-security | ||
| 21 | Upstream commit https://github.com/sudo-project/sudo/commit/334daf92b31b79ce68ed75e2ee14fca265f029ca] | ||
| 22 | CVE: CVE-2023-28486 CVE-2023-28487 | ||
| 23 | Signed-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 @@ | |||
| 1 | Backport of: | ||
| 2 | |||
| 3 | From 12648b4e0a8cf486480442efd52f0e0b6cab6e8b Mon Sep 17 00:00:00 2001 | ||
| 4 | From: "Todd C. Miller" <Todd.Miller@sudo.ws> | ||
| 5 | Date: Mon, 13 Mar 2023 08:04:32 -0600 | ||
| 6 | Subject: [PATCH] Add missing " ; " separator between environment variables and | ||
| 7 | command. This is a regression introduced in sudo 1.9.13. GitHub issue #254. | ||
| 8 | |||
| 9 | Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches/CVE-2023-2848x-2.patch?h=ubuntu/focal-security | ||
| 10 | Upstream commit https://github.com/sudo-project/sudo/commit/12648b4e0a8cf486480442efd52f0e0b6cab6e8b] | ||
| 11 | CVE: CVE-2023-28486 CVE-2023-28487 | ||
| 12 | Signed-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 5bc48ec6fa..e35bbfa789 100644 --- a/meta/recipes-extended/sudo/sudo_1.8.32.bb +++ b/meta/recipes-extended/sudo/sudo_1.8.32.bb | |||
| @@ -6,6 +6,8 @@ SRC_URI = "https://www.sudo.ws/dist/sudo-${PV}.tar.gz \ | |||
| 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 \ | 7 | file://CVE-2022-43995.patch \ |
| 8 | file://CVE-2023-22809.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 \ | ||
| 9 | " | 11 | " |
| 10 | 12 | ||
| 11 | PAM_SRC_URI = "file://sudo.pam" | 13 | PAM_SRC_URI = "file://sudo.pam" |
