Browse Source

sudo update CVE-2021-3156

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 4 years ago
parent
commit
0a01f7450e
  1. 207
      SOURCES/sudo-1.8.31-CVE-2021-3156.patch
  2. 12
      SPECS/sudo.spec

207
SOURCES/sudo-1.8.31-CVE-2021-3156.patch

@ -0,0 +1,207 @@
diff -up ./plugins/sudoers/policy.c.heap-buffer ./plugins/sudoers/policy.c
--- ./plugins/sudoers/policy.c.heap-buffer 2021-01-20 13:10:29.368619293 +0100
+++ ./plugins/sudoers/policy.c 2021-01-20 15:56:12.915095745 +0100
@@ -93,11 +93,12 @@ 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_policy_open_info *info = v;
- char * const *cur;
const char *p, *errstr, *groups = NULL;
const char *remhost = NULL;
bool uid_set = false, gid_set = false;
+ char * const *cur;
int flags = 0;
debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN)
@@ -326,6 +327,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_umask = (mode_t)-1;
for (cur = info->user_info; *cur != NULL; cur++) {
if (MATCHES(*cur, "user=")) {
diff -up ./plugins/sudoers/sudoers.c.heap-buffer ./plugins/sudoers/sudoers.c
--- ./plugins/sudoers/sudoers.c.heap-buffer 2021-01-20 13:10:29.350619537 +0100
+++ ./plugins/sudoers/sudoers.c 2021-01-20 13:10:29.369619280 +0100
@@ -416,7 +416,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;
@@ -796,8 +796,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))
@@ -835,7 +835,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
@@ -843,10 +844,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 -up ./plugins/sudoers/timestamp.c.heap-buffer ./plugins/sudoers/timestamp.c
--- ./plugins/sudoers/timestamp.c.heap-buffer 2018-09-02 14:30:08.000000000 +0200
+++ ./plugins/sudoers/timestamp.c 2021-01-20 13:10:29.369619280 +0100
@@ -646,8 +646,8 @@ timestamp_lock(void *vcookie, struct pas
} else if (entry.type != TS_LOCKEXCL) {
/* Old sudo record, convert it to TS_LOCKEXCL. */
entry.type = TS_LOCKEXCL;
- memset((char *)&entry + offsetof(struct timestamp_entry, type), 0,
- nread - offsetof(struct timestamp_entry, type));
+ 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);
}
diff -up ./src/parse_args.c.heap-buffer ./src/parse_args.c
--- ./src/parse_args.c.heap-buffer 2018-08-18 16:10:25.000000000 +0200
+++ ./src/parse_args.c 2021-01-20 16:01:42.500778441 +0100
@@ -116,7 +116,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
@@ -260,6 +263,7 @@ parse_args(int argc, char **argv, int *n
progname = "sudoedit";
mode = MODE_EDIT;
sudo_settings[ARG_SUDOEDIT].value = "true";
+ valid_flags = EDIT_VALID_FLAGS;
}
/* Load local IP addresses and masks. */
@@ -345,7 +349,7 @@ parse_args(int argc, char **argv, int *n
usage_excl(1);
mode = MODE_EDIT;
sudo_settings[ARG_SUDOEDIT].value = "true";
- valid_flags = MODE_NONINTERACTIVE;
+ valid_flags = EDIT_VALID_FLAGS;
break;
case 'g':
if (*optarg == '\0')
@@ -355,6 +359,7 @@ parse_args(int argc, char **argv, int *n
break;
case 'H':
sudo_settings[ARG_SET_HOME].value = "true";
+ SET(flags, MODE_RESET_HOME);
break;
case 'h':
if (optarg == NULL) {
@@ -404,7 +409,7 @@ parse_args(int argc, char **argv, int *n
usage_excl(1);
}
mode = MODE_LIST;
- valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST;
+ valid_flags = LIST_VALID_FLAGS;
break;
case 'n':
SET(flags, MODE_NONINTERACTIVE);
@@ -412,6 +417,7 @@ parse_args(int argc, char **argv, int *n
break;
case 'P':
sudo_settings[ARG_PRESERVE_GROUPS].value = "true";
+ SET(flags, MODE_PRESERVE_GROUPS);
break;
case 'p':
/* An empty prompt is allowed. */
@@ -455,7 +461,7 @@ parse_args(int argc, char **argv, int *n
if (mode && mode != MODE_VALIDATE)
usage_excl(1);
mode = MODE_VALIDATE;
- valid_flags = MODE_NONINTERACTIVE;
+ valid_flags = VALIDATE_VALID_FLAGS;
break;
case 'V':
if (mode && mode != MODE_VERSION)
@@ -482,7 +488,7 @@ parse_args(int argc, char **argv, int *n
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;
@@ -545,23 +551,24 @@ parse_args(int argc, char **argv, int *n
/*
* 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;
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(1);
- 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 != '$')

12
SPECS/sudo.spec

@ -1,7 +1,7 @@
Summary: Allows restricted root access for specified users Summary: Allows restricted root access for specified users
Name: sudo Name: sudo
Version: 1.8.23 Version: 1.8.23
Release: 10%{?dist} Release: 11%{?dist}
License: ISC License: ISC
Group: Applications/System Group: Applications/System
URL: http://www.courtesan.com/sudo/ URL: http://www.courtesan.com/sudo/
@ -74,6 +74,9 @@ Patch16: sudo-1.8.29-CVE-2019-18634-part2.patch
Patch17: sudo-1.8.29-expired-password-part1.patch Patch17: sudo-1.8.29-expired-password-part1.patch
Patch18: sudo-1.8.29-expired-password-part2.patch Patch18: sudo-1.8.29-expired-password-part2.patch


# 1917729 - EMBARGOED CVE-2021-3156 sudo: Heap-buffer overflow in argument parsing [rhel-7.9.z]
Patch19: sudo-1.8.31-CVE-2021-3156.patch

%description %description
Sudo (superuser do) allows a system administrator to give certain Sudo (superuser do) allows a system administrator to give certain
users (or groups of users) the ability to run some (or all) commands users (or groups of users) the ability to run some (or all) commands
@ -121,6 +124,8 @@ plugins that use %{name}.
%patch17 -p1 -b .expired-password-part1 %patch17 -p1 -b .expired-password-part1
%patch18 -p1 -b .expired-password-part2 %patch18 -p1 -b .expired-password-part2


%patch19 -p1 -b .heap-buffer

%build %build
autoreconf -I m4 -fv --install autoreconf -I m4 -fv --install


@ -256,6 +261,11 @@ rm -rf %{buildroot}
%{_mandir}/man8/sudo_plugin.8* %{_mandir}/man8/sudo_plugin.8*


%changelog %changelog
* Wed Jan 20 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.23-11
- RHEL 7.9.Z ERRATUM
- CVE-2021-3156
Resolves: rhbz#1917729

* Wed Mar 25 2020 Radovan Sroka <rsroka@redhat.com> - 1.8.23-10 * Wed Mar 25 2020 Radovan Sroka <rsroka@redhat.com> - 1.8.23-10
- RHEL-7.9 - RHEL-7.9
- sudo allows privilege escalation with expire password - sudo allows privilege escalation with expire password

Loading…
Cancel
Save