diff options
author | Christopher Fore <csfore@posteo.net> | 2024-04-24 09:21:02 -0400 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2024-05-03 12:18:53 +0100 |
commit | 26a218c56917878f75b6fa995d3336de799462f1 (patch) | |
tree | 85e926dd89c6be00a946238a69c48972864df7dd /media-gfx | |
parent | media-libs/libde265: sync live (diff) | |
download | gentoo-26a218c56917878f75b6fa995d3336de799462f1.tar.gz gentoo-26a218c56917878f75b6fa995d3336de799462f1.tar.bz2 gentoo-26a218c56917878f75b6fa995d3336de799462f1.zip |
media-gfx/fontforge: Add security patch
- CVE-2024-25081, CVE-2024-25082
- Tests pass
- Revbump
Bug: https://bugs.gentoo.org/926521
Signed-off-by: Christopher Fore <csfore@posteo.net>
Closes: https://github.com/gentoo/gentoo/pull/36405
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'media-gfx')
-rw-r--r-- | media-gfx/fontforge/files/fontforge-20230101-fix-splinefont-shell-command-injection.patch | 174 | ||||
-rw-r--r-- | media-gfx/fontforge/fontforge-20230101-r1.ebuild | 111 |
2 files changed, 285 insertions, 0 deletions
diff --git a/media-gfx/fontforge/files/fontforge-20230101-fix-splinefont-shell-command-injection.patch b/media-gfx/fontforge/files/fontforge-20230101-fix-splinefont-shell-command-injection.patch new file mode 100644 index 000000000000..e61f2b8d3633 --- /dev/null +++ b/media-gfx/fontforge/files/fontforge-20230101-fix-splinefont-shell-command-injection.patch @@ -0,0 +1,174 @@ +https://github.com/fontforge/fontforge/commit/216eb14b558df344b206bf82e2bdaf03a1f2f429 + +From 216eb14b558df344b206bf82e2bdaf03a1f2f429 Mon Sep 17 00:00:00 2001 +From: Peter Kydas <pk@canva.com> +Date: Tue, 6 Feb 2024 20:03:04 +1100 +Subject: [PATCH] fix splinefont shell command injection (#5367) + +--- a/fontforge/splinefont.c ++++ b/fontforge/splinefont.c +@@ -788,11 +788,14 @@ return( name ); + + char *Unarchive(char *name, char **_archivedir) { + char *dir = getenv("TMPDIR"); +- char *pt, *archivedir, *listfile, *listcommand, *unarchivecmd, *desiredfile; ++ char *pt, *archivedir, *listfile, *desiredfile; + char *finalfile; + int i; + int doall=false; + static int cnt=0; ++ gchar *command[5]; ++ gchar *stdoutresponse = NULL; ++ gchar *stderrresponse = NULL; + + *_archivedir = NULL; + +@@ -827,18 +830,30 @@ return( NULL ); + listfile = malloc(strlen(archivedir)+strlen("/" TOC_NAME)+1); + sprintf( listfile, "%s/" TOC_NAME, archivedir ); + +- listcommand = malloc( strlen(archivers[i].unarchive) + 1 + +- strlen( archivers[i].listargs) + 1 + +- strlen( name ) + 3 + +- strlen( listfile ) +4 ); +- sprintf( listcommand, "%s %s %s > %s", archivers[i].unarchive, +- archivers[i].listargs, name, listfile ); +- if ( system(listcommand)!=0 ) { +- free(listcommand); free(listfile); +- ArchiveCleanup(archivedir); +-return( NULL ); +- } +- free(listcommand); ++ command[0] = archivers[i].unarchive; ++ command[1] = archivers[i].listargs; ++ command[2] = name; ++ command[3] = NULL; // command args need to be NULL-terminated ++ ++ if ( g_spawn_sync( ++ NULL, ++ command, ++ NULL, ++ G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ &stdoutresponse, ++ &stderrresponse, ++ NULL, ++ NULL ++ ) == FALSE) { // did not successfully execute ++ ArchiveCleanup(archivedir); ++ return( NULL ); ++ } ++ // Write out the listfile to be read in later ++ FILE *fp = fopen(listfile, "wb"); ++ fwrite(stdoutresponse, strlen(stdoutresponse), 1, fp); ++ fclose(fp); + + desiredfile = ArchiveParseTOC(listfile, archivers[i].ars, &doall); + free(listfile); +@@ -847,22 +862,28 @@ return( NULL ); + return( NULL ); + } + +- /* I tried sending everything to stdout, but that doesn't work if the */ +- /* output is a directory file (ufo, sfdir) */ +- unarchivecmd = malloc( strlen(archivers[i].unarchive) + 1 + +- strlen( archivers[i].listargs) + 1 + +- strlen( name ) + 1 + +- strlen( desiredfile ) + 3 + +- strlen( archivedir ) + 30 ); +- sprintf( unarchivecmd, "( cd %s ; %s %s %s %s ) > /dev/null", archivedir, +- archivers[i].unarchive, +- archivers[i].extractargs, name, doall ? "" : desiredfile ); +- if ( system(unarchivecmd)!=0 ) { +- free(unarchivecmd); free(desiredfile); +- ArchiveCleanup(archivedir); +-return( NULL ); ++ command[0] = archivers[i].unarchive; ++ command[1] = archivers[i].extractargs; ++ command[2] = name; ++ command[3] = doall ? "" : desiredfile; ++ command[4] = NULL; ++ ++ if ( g_spawn_sync( ++ (gchar*)archivedir, ++ command, ++ NULL, ++ G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ &stdoutresponse, ++ &stderrresponse, ++ NULL, ++ NULL ++ ) == FALSE) { // did not successfully execute ++ free(desiredfile); ++ ArchiveCleanup(archivedir); ++ return( NULL ); + } +- free(unarchivecmd); + + finalfile = malloc( strlen(archivedir) + 1 + strlen(desiredfile) + 1); + sprintf( finalfile, "%s/%s", archivedir, desiredfile ); +@@ -885,20 +906,54 @@ struct compressors compressors[] = { + + char *Decompress(char *name, int compression) { + char *dir = getenv("TMPDIR"); +- char buf[1500]; + char *tmpfn; +- ++ gchar *command[4]; ++ gint stdout_pipe; ++ gchar buffer[4096]; ++ gssize bytes_read; ++ GByteArray *binary_data = g_byte_array_new(); ++ + if ( dir==NULL ) dir = P_tmpdir; + tmpfn = malloc(strlen(dir)+strlen(GFileNameTail(name))+2); + strcpy(tmpfn,dir); + strcat(tmpfn,"/"); + strcat(tmpfn,GFileNameTail(name)); + *strrchr(tmpfn,'.') = '\0'; +- snprintf( buf, sizeof(buf), "%s < %s > %s", compressors[compression].decomp, name, tmpfn ); +- if ( system(buf)==0 ) +-return( tmpfn ); +- free(tmpfn); +-return( NULL ); ++ ++ command[0] = compressors[compression].decomp; ++ command[1] = "-c"; ++ command[2] = name; ++ command[3] = NULL; ++ ++ // Have to use async because g_spawn_sync doesn't handle nul-bytes in the output (which happens with binary data) ++ if (g_spawn_async_with_pipes( ++ NULL, ++ command, ++ NULL, ++ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ &stdout_pipe, ++ NULL, ++ NULL) == FALSE) { ++ //command has failed ++ return( NULL ); ++ } ++ ++ // Read binary data from pipe and output to file ++ while ((bytes_read = read(stdout_pipe, buffer, sizeof(buffer))) > 0) { ++ g_byte_array_append(binary_data, (guint8 *)buffer, bytes_read); ++ } ++ close(stdout_pipe); ++ ++ FILE *fp = fopen(tmpfn, "wb"); ++ fwrite(binary_data->data, sizeof(gchar), binary_data->len, fp); ++ fclose(fp); ++ g_byte_array_free(binary_data, TRUE); ++ ++ return(tmpfn); + } + + static char *ForceFileToHaveName(FILE *file, char *exten) { diff --git a/media-gfx/fontforge/fontforge-20230101-r1.ebuild b/media-gfx/fontforge/fontforge-20230101-r1.ebuild new file mode 100644 index 000000000000..acbd7a1c4708 --- /dev/null +++ b/media-gfx/fontforge/fontforge-20230101-r1.ebuild @@ -0,0 +1,111 @@ +# Copyright 2004-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +PYTHON_COMPAT=( python3_{9..11} ) +inherit python-single-r1 xdg cmake + +DESCRIPTION="postscript font editor and converter" +HOMEPAGE="https://fontforge.org/" +SRC_URI="https://github.com/fontforge/fontforge/releases/download/${PV}/${P}.tar.xz" + +LICENSE="BSD GPL-3+" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux ~ppc-macos" +IUSE="doc truetype-debugger gif gtk jpeg png +python readline test tiff svg woff2 X" +RESTRICT="!test? ( test )" +REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )" + +RDEPEND=" + >=dev-libs/glib-2.67:2 + dev-libs/libltdl:0 + dev-libs/libxml2:2= + >=media-libs/freetype-2.3.7:2= + gif? ( media-libs/giflib:= ) + jpeg? ( media-libs/libjpeg-turbo:= ) + png? ( media-libs/libpng:= ) + tiff? ( media-libs/tiff:= ) + truetype-debugger? ( >=media-libs/freetype-2.3.8:2[fontforge,-bindist(-)] ) + gtk? ( >=x11-libs/gtk+-3.10:3 ) + !gtk? ( + X? ( + >=x11-libs/cairo-1.6:0= + >=x11-libs/pango-1.10:0=[X] + x11-libs/libX11:= + x11-libs/libXi:= + ) + ) + python? ( ${PYTHON_DEPS} ) + readline? ( sys-libs/readline:0= ) + woff2? ( media-libs/woff2:0= ) +" +DEPEND="${RDEPEND} + !gtk? ( X? ( x11-base/xorg-proto ) ) +" +BDEPEND=" + sys-devel/gettext + doc? ( >=dev-python/sphinx-2 ) + python? ( ${PYTHON_DEPS} ) + test? ( ${RDEPEND} ) +" + +PATCHES=( + "${FILESDIR}"/fontforge-doc-no-warn-error.patch + "${FILESDIR}"/${PN}-20230101-workaround-broken-translations.patch + "${FILESDIR}"/${PN}-20230101-fix-splinefont-shell-command-injection.patch +) + +pkg_setup() { + use python && python-single-r1_pkg_setup +} + +src_configure() { + local mycmakeargs=( + -DENABLE_DOCS=$(usex doc ON OFF) + -DENABLE_LIBGIF=$(usex gif ON OFF) + -DENABLE_LIBJPEG=$(usex jpeg ON OFF) + -DENABLE_LIBPNG=$(usex png ON OFF) + -DENABLE_LIBREADLINE=$(usex readline ON OFF) + -DENABLE_LIBSPIRO=OFF # No package in Gentoo + -DENABLE_LIBTIFF=$(usex tiff ON OFF) + -DENABLE_MAINTAINER_TOOLS=OFF + -DENABLE_PYTHON_EXTENSION=$(usex python ON OFF) + -DENABLE_PYTHON_SCRIPTING=$(usex python ON OFF) + -DENABLE_TILE_PATH=ON + -DENABLE_WOFF2=$(usex woff2 ON OFF) + ) + + if use gtk || use X; then + mycmakeargs+=( + -DENABLE_GUI=ON + # Prefer GTK over X11 if both USE flage are enabled + -DENABLE_X11=$(usex gtk OFF ON) + ) + else + mycmakeargs+=( -DENABLE_GUI=OFF ) + fi + + if use python; then + python_setup + mycmakeargs+=( -DPython3_EXECUTABLE="${PYTHON}" ) + fi + + if use truetype-debugger ; then + local ft2="${ESYSROOT}/usr/include/freetype2" + local ft2i="${ft2}/internal4fontforge" + mycmakeargs+=( + -DENABLE_FREETYPE_DEBUGGER="${ft2}" + -DFreeTypeSource_INCLUDE_DIRS="${ft2};${ft2i}/include;${ft2i}/include/freetype;${ft2i}/src/truetype" + ) + fi + + cmake_src_configure +} + +src_install() { + cmake_src_install + docompress -x /usr/share/doc/${PF}/html + einstalldocs + find "${ED}" -name '*.la' -type f -delete || die +} |