- Resolves: RHEL-215573 - Use canonicalized path if user path contains ".."
This commit is contained in:
parent
44d155ed75
commit
a32936288e
157
0006-RHEL-215573-dot-dot.patch
Normal file
157
0006-RHEL-215573-dot-dot.patch
Normal file
@ -0,0 +1,157 @@
|
||||
From f8163e5ea3ec204727c77cfd06fec788ad9679f4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Alejandro=20L=C3=B3pez?= <allopez@redhat.com>
|
||||
Date: Tue, 7 Jul 2026 17:00:14 +0200
|
||||
Subject: [PATCH] RHEL-189002: dot_dot
|
||||
|
||||
Minimal backport of commits 620ba7a3880d9934b349c28c9a670a8346a37c91 and
|
||||
8443ab434e20f8003ca4bc11783462401722b987
|
||||
---
|
||||
include/sudo_util.h | 4 +++
|
||||
lib/util/Makefile.in | 20 +++++++++----
|
||||
lib/util/dotdot.c | 51 +++++++++++++++++++++++++++++++++
|
||||
lib/util/util.exp.in | 1 +
|
||||
plugins/sudoers/match_command.c | 6 ++--
|
||||
5 files changed, 75 insertions(+), 7 deletions(-)
|
||||
create mode 100644 lib/util/dotdot.c
|
||||
|
||||
diff --git a/include/sudo_util.h b/include/sudo_util.h
|
||||
index 2da62d6..fdd81db 100644
|
||||
--- a/include/sudo_util.h
|
||||
+++ b/include/sudo_util.h
|
||||
@@ -182,6 +182,10 @@ sudo_dso_public int aix_setauthdb_v2(char *user, char *registry);
|
||||
sudo_dso_public char *sudo_basename_v1(const char *filename);
|
||||
#define sudo_basename(_a) sudo_basename_v1(_a)
|
||||
|
||||
+/* dotdot.c */
|
||||
+sudo_dso_public bool sudo_contains_dot_dot_v1(const char *str);
|
||||
+#define sudo_contains_dot_dot(_a) sudo_contains_dot_dot_v1(_a)
|
||||
+
|
||||
/* gethostname.c */
|
||||
sudo_dso_public char *sudo_gethostname_v1(void);
|
||||
#define sudo_gethostname() sudo_gethostname_v1()
|
||||
diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in
|
||||
index 428a127..695ab8a 100644
|
||||
--- a/lib/util/Makefile.in
|
||||
+++ b/lib/util/Makefile.in
|
||||
@@ -145,7 +145,7 @@ DEVEL = @DEVEL@
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
-LTOBJS = basename.lo @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
|
||||
+LTOBJS = basename.lo @DIGEST@ dotdot.lo event.lo fatal.lo key_val.lo gethostname.lo \
|
||||
gettime.lo getgrouplist.lo gidlist.lo hexchar.lo json.lo lbuf.lo \
|
||||
locking.lo logfac.lo login_max.lo logpri.lo mkdir_parents.lo \
|
||||
mmap_alloc.lo multiarch.lo parseln.lo progname.lo rcstr.lo regex.lo \
|
||||
@@ -678,6 +678,16 @@ digest_test.i: $(srcdir)/regress/digest/digest_test.c \
|
||||
$(CPP) $(CPPFLAGS) $(srcdir)/regress/digest/digest_test.c > $@
|
||||
digest_test.plog: digest_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/digest/digest_test.c --i-file digest_test.i --output-file $@
|
||||
+dotdot.lo: $(srcdir)/dotdot.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/dotdot.c
|
||||
+dotdot.i: $(srcdir)/dotdot.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(CPP) $(CPPFLAGS) $(srcdir)/dotdot.c > $@
|
||||
+dotdot.plog: dotdot.i
|
||||
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --source-file $(srcdir)/dotdot.c --i-file dotdot.i --output-file $@
|
||||
dup3.lo: $(srcdir)/dup3.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/dup3.c
|
||||
dup3.i: $(srcdir)/dup3.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
diff --git a/lib/util/dotdot.c b/lib/util/dotdot.c
|
||||
new file mode 100644
|
||||
index 0000000..66fd2bb
|
||||
--- /dev/null
|
||||
+++ b/lib/util/dotdot.c
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * SPDX-License-Identifier: ISC
|
||||
+ *
|
||||
+ * Copyright (c) 2025 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#ifdef HAVE_STDBOOL_H
|
||||
+# include <stdbool.h>
|
||||
+#else
|
||||
+# include <compat/stdbool.h>
|
||||
+#endif /* HAVE_STDBOOL_H */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <sudo_compat.h>
|
||||
+#include <sudo_debug.h>
|
||||
+#include <sudo_util.h>
|
||||
+
|
||||
+bool
|
||||
+sudo_contains_dot_dot_v1(const char *str)
|
||||
+{
|
||||
+ const char *cp;
|
||||
+ debug_decl(sudo_contains_dot_dot, SUDO_DEBUG_UTIL);
|
||||
+
|
||||
+ for (cp = str; *cp != '\0'; cp++) {
|
||||
+ /* Match ".." */
|
||||
+ if (cp[0] != '.' || cp[1] != '.')
|
||||
+ continue;
|
||||
+
|
||||
+ /* Match "^.." or "/.." then "../" or "..$" */
|
||||
+ if ((cp == str || cp[-1] == '/') && (cp[2] == '/' || cp[2] == '\0'))
|
||||
+ debug_return_bool(true);
|
||||
+ }
|
||||
+
|
||||
+ debug_return_bool(false);
|
||||
+}
|
||||
diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in
|
||||
index 0363147..98af276 100644
|
||||
--- a/lib/util/util.exp.in
|
||||
+++ b/lib/util/util.exp.in
|
||||
@@ -17,6 +17,7 @@ sudo_conf_plugins_v1
|
||||
sudo_conf_probe_interfaces_v1
|
||||
sudo_conf_read_v1
|
||||
sudo_conf_sesh_path_v1
|
||||
+sudo_contains_dot_dot_v1
|
||||
sudo_debug_deregister_v1
|
||||
sudo_debug_enter_v1
|
||||
sudo_debug_execve2_v1
|
||||
diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c
|
||||
index dc4d244..b2d231e 100644
|
||||
--- a/plugins/sudoers/match_command.c
|
||||
+++ b/plugins/sudoers/match_command.c
|
||||
@@ -423,7 +423,8 @@ command_matches_fnmatch(struct sudoers_context *ctx, const char *sudoers_cmnd,
|
||||
* We do not attempt to match a relative path unless there is a
|
||||
* canonicalized version.
|
||||
*/
|
||||
- if (cmnd[0] != '/' || fnmatch(sudoers_cmnd, cmnd, FNM_PATHNAME) != 0) {
|
||||
+ if (cmnd[0] != '/' || sudo_contains_dot_dot(cmnd) ||
|
||||
+ fnmatch(sudoers_cmnd, cmnd, FNM_PATHNAME) != 0) {
|
||||
/* No match, retry using the canonicalized path (if possible). */
|
||||
if (ctx->user.cmnd_dir == NULL)
|
||||
debug_return_int(DENY);
|
||||
@@ -480,7 +481,8 @@ command_matches_regex(struct sudoers_context *ctx, const char *sudoers_cmnd,
|
||||
*
|
||||
* Neither sudoers_cmnd nor user_cmnd are relative to runchroot.
|
||||
*/
|
||||
- if (cmnd[0] != '/' || regex_matches(sudoers_cmnd, cmnd) != ALLOW) {
|
||||
+ if (cmnd[0] != '/' || sudo_contains_dot_dot(cmnd) ||
|
||||
+ regex_matches(sudoers_cmnd, cmnd) != ALLOW) {
|
||||
/* No match, retry using the canonicalized path (if possible). */
|
||||
if (ctx->user.cmnd_dir == NULL)
|
||||
debug_return_int(DENY);
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -31,6 +31,7 @@ Patch2: 0002-sudo-conf.patch
|
||||
Patch3: 0003-rebuild_env-Avoid-setting-SHELL-twice-for-sudo-i.patch
|
||||
Patch4: 0004-cve-2026-35535.patch
|
||||
Patch5: 0005-exec_pty-Treat-a-socketpair-for-stdin-stdout-same-as.patch
|
||||
Patch6: 0006-RHEL-215573-dot-dot.patch
|
||||
|
||||
%description
|
||||
Sudo (superuser do) allows a system administrator to give certain
|
||||
|
||||
Loading…
Reference in New Issue
Block a user