forked from pool/libXpm
* needed by U_0005-Fix-CVE-2022-4883-compression-commands-depend-on-PAT.patch - U_0002-Fix-CVE-2022-46285-Infinite-loop-on-unclosed-comment.patch * libXpm: Infinite loop on unclosed comments (CVE-2022-46285, bsc#1207029) - U_0004-Fix-CVE-2022-44617-Runaway-loop-with-width-of-0-and-.patch * libXpm: Runaway loop on width of 0 and enormous height (CVE-2022-44617, bsc#1207030) - U_0005-Fix-CVE-2022-4883-compression-commands-depend-on-PAT.patch * libXpm: compression commands depend on $PATH (CVE-2022-4883, bsc#1207031) - U_regression-bug1207029_1207030_1207031.patch * regression fix for above patches - U_regression2-bug1207029_1207030_1207031.patch * second regression fix: Use gzip -d instead of gunzip OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/libXpm?expand=0&rev=18
142 lines
5.3 KiB
Diff
142 lines
5.3 KiB
Diff
From 082a080672c3b8a964aa8100bee41930e12b03fa Mon Sep 17 00:00:00 2001
|
|
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
Date: Fri, 6 Jan 2023 12:50:48 -0800
|
|
Subject: [PATCH libXpm 5/5] Fix CVE-2022-4883: compression commands depend on
|
|
$PATH
|
|
|
|
By default, on all platforms except MinGW, libXpm will detect if a
|
|
filename ends in .Z or .gz, and will when reading such a file fork off
|
|
an uncompress or gunzip command to read from via a pipe, and when
|
|
writing such a file will fork off a compress or gzip command to write
|
|
to via a pipe.
|
|
|
|
In libXpm 3.5.14 or older these are run via execlp(), relying on $PATH
|
|
to find the commands. If libXpm is called from a program running with
|
|
raised privileges, such as via setuid, then a malicious user could set
|
|
$PATH to include programs of their choosing to be run with those
|
|
privileges.
|
|
|
|
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
---
|
|
README.md | 12 ++++++++++++
|
|
configure.ac | 14 ++++++++++++++
|
|
src/RdFToI.c | 17 ++++++++++++++---
|
|
src/WrFFrI.c | 4 ++--
|
|
4 files changed, 42 insertions(+), 5 deletions(-)
|
|
|
|
Index: libXpm-3.5.14/README.md
|
|
===================================================================
|
|
--- libXpm-3.5.14.orig/README.md
|
|
+++ libXpm-3.5.14/README.md
|
|
@@ -31,3 +31,15 @@ if it can't find the file it was asked t
|
|
--enable-open-zfile feature to open the file, and is enabled by default
|
|
when --enable-open-zfile is enabled, and can be disabled by passing the
|
|
--disable-stat-zfile flag to the configure script.
|
|
+
|
|
+All of these commands will be executed with whatever userid & privileges the
|
|
+function is called with, relying on the caller to ensure the correct euid,
|
|
+egid, etc. are set before calling.
|
|
+
|
|
+To reduce risk, the paths to these commands are now set at configure time to
|
|
+the first version found in the PATH used to run configure, and do not depend
|
|
+on the PATH environment variable set at runtime.
|
|
+
|
|
+To specify paths to be used for these commands instead of searching $PATH, pass
|
|
+the XPM_PATH_COMPRESS, XPM_PATH_UNCOMPRESS, XPM_PATH_GZIP, and XPM_PATH_GUNZIP
|
|
+variables to the configure command.
|
|
Index: libXpm-3.5.14/configure.ac
|
|
===================================================================
|
|
--- libXpm-3.5.14.orig/configure.ac
|
|
+++ libXpm-3.5.14/configure.ac
|
|
@@ -49,6 +49,14 @@ if test "x$USE_GETTEXT" = "xyes" ; then
|
|
fi
|
|
AM_CONDITIONAL(USE_GETTEXT, test "x$USE_GETTEXT" = "xyes")
|
|
|
|
+dnl Helper macro to find absolute path to program and add a #define for it
|
|
+AC_DEFUN([XPM_PATH_PROG],[
|
|
+AC_PATH_PROG([$1], [$2], [])
|
|
+AS_IF([test "x$$1" = "x"],
|
|
+ [AC_MSG_ERROR([$2 not found, set $1 or use --disable-open-zfile])])
|
|
+AC_DEFINE_UNQUOTED([$1], ["$$1"], [Path to $2])
|
|
+]) dnl End of AC_DEFUN([XPM_PATH_PROG]...
|
|
+
|
|
# Optional feature: When a filename ending in .Z or .gz is requested,
|
|
# open a pipe to a newly forked compress/uncompress/gzip/gunzip command to
|
|
# handle it.
|
|
@@ -64,6 +72,11 @@ AC_ARG_ENABLE(open-zfile,
|
|
AC_MSG_RESULT([$OPEN_ZFILE])
|
|
if test x$OPEN_ZFILE = xno ; then
|
|
AC_DEFINE(NO_ZPIPE, 1, [Define to 1 to disable decompression via pipes])
|
|
+else
|
|
+ XPM_PATH_PROG([XPM_PATH_UNCOMPRESS], [uncompress])
|
|
+ XPM_PATH_PROG([XPM_PATH_GZIP], [gzip])
|
|
+ XPM_PATH_PROG([XPM_PATH_GUNZIP], [gunzip])
|
|
+ AC_CHECK_FUNCS([closefrom close_range], [break])
|
|
fi
|
|
|
|
# Optional feature: When ___.xpm is requested, also look for ___.xpm.Z & .gz
|
|
Index: libXpm-3.5.14/src/RdFToI.c
|
|
===================================================================
|
|
--- libXpm-3.5.14.orig/src/RdFToI.c
|
|
+++ libXpm-3.5.14/src/RdFToI.c
|
|
@@ -43,6 +43,7 @@
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
+#include <unistd.h>
|
|
#else
|
|
#ifdef FOR_MSW
|
|
#include <fcntl.h>
|
|
@@ -161,7 +162,17 @@ xpmPipeThrough(
|
|
goto err;
|
|
if ( 0 == pid )
|
|
{
|
|
- execlp(cmd, cmd, arg1, (char *)NULL);
|
|
+#ifdef HAVE_CLOSEFROM
|
|
+ closefrom(3);
|
|
+#elif defined(HAVE_CLOSE_RANGE)
|
|
+# ifdef CLOSE_RANGE_UNSHARE
|
|
+# define close_range_flags CLOSE_RANGE_UNSHARE
|
|
+# else
|
|
+# define close_range_flags 0
|
|
+#endif
|
|
+ close_range(3, ~0U, close_range_flags);
|
|
+#endif
|
|
+ execl(cmd, cmd, arg1, (char *)NULL);
|
|
perror(cmd);
|
|
goto err;
|
|
}
|
|
@@ -235,12 +246,12 @@ OpenReadFile(
|
|
if ( ext && !strcmp(ext, ".Z") )
|
|
{
|
|
mdata->type = XPMPIPE;
|
|
- mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
|
|
+ mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_UNCOMPRESS, "-c", "r");
|
|
}
|
|
else if ( ext && !strcmp(ext, ".gz") )
|
|
{
|
|
mdata->type = XPMPIPE;
|
|
- mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
|
|
+ mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_GUNZIP, "-qc", "r");
|
|
}
|
|
else
|
|
#endif /* z-files */
|
|
Index: libXpm-3.5.14/src/WrFFrI.c
|
|
===================================================================
|
|
--- libXpm-3.5.14.orig/src/WrFFrI.c
|
|
+++ libXpm-3.5.14/src/WrFFrI.c
|
|
@@ -342,10 +342,10 @@ OpenWriteFile(
|
|
#ifndef NO_ZPIPE
|
|
len = strlen(filename);
|
|
if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
|
|
- mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
|
|
- mdata->type = XPMPIPE;
|
|
+ /* No compress program available (any longer?) on Linux */
|
|
+ mdata->stream.file = NULL;
|
|
} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
|
|
- mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
|
|
+ mdata->stream.file = xpmPipeThrough(fd, XPM_PATH_GZIP, "-q", "w");
|
|
mdata->type = XPMPIPE;
|
|
} else
|
|
#endif
|