Gentoo Archives: gentoo-commits

From: Sam James <sam@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: app-text/ghostscript-gpl/, app-text/ghostscript-gpl/files/
Date: Mon, 13 Sep 2021 00:54:34
Message-Id: 1631494458.eeb37a3981b77ed60be7975287e1a503375fa493.sam@gentoo
1 commit: eeb37a3981b77ed60be7975287e1a503375fa493
2 Author: Sam James <sam <AT> gentoo <DOT> org>
3 AuthorDate: Mon Sep 13 00:53:50 2021 +0000
4 Commit: Sam James <sam <AT> gentoo <DOT> org>
5 CommitDate: Mon Sep 13 00:54:18 2021 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=eeb37a39
7
8 app-text/ghostscript-gpl: patch CVE-2021-3781
9
10 Bug: https://bugs.gentoo.org/812509
11 Signed-off-by: Sam James <sam <AT> gentoo.org>
12
13 .../ghostscript-gpl-9.54.0-CVE-2021-3781.patch | 213 +++++++++++++++++++++
14 .../ghostscript-gpl-9.54.0-r1.ebuild | 191 ++++++++++++++++++
15 2 files changed, 404 insertions(+)
16
17 diff --git a/app-text/ghostscript-gpl/files/ghostscript-gpl-9.54.0-CVE-2021-3781.patch b/app-text/ghostscript-gpl/files/ghostscript-gpl-9.54.0-CVE-2021-3781.patch
18 new file mode 100644
19 index 00000000000..779bedad4bd
20 --- /dev/null
21 +++ b/app-text/ghostscript-gpl/files/ghostscript-gpl-9.54.0-CVE-2021-3781.patch
22 @@ -0,0 +1,213 @@
23 +https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=a9bd3dec9fde03327a4a2c69dad1036bf9632e20
24 +https://bugs.gentoo.org/812509
25 +
26 +From: Chris Liddell <chris.liddell@×××××××.com>
27 +Date: Tue, 7 Sep 2021 20:36:12 +0100
28 +Subject: [PATCH 1/1] Bug 704342: Include device specifier strings in access
29 + validation
30 +
31 +for the "%pipe%", %handle%" and %printer% io devices.
32 +
33 +We previously validated only the part after the "%pipe%" Postscript device
34 +specifier, but this proved insufficient.
35 +
36 +This rebuilds the original file name string, and validates it complete. The
37 +slight complication for "%pipe%" is it can be reached implicitly using
38 +"|" so we have to check both prefixes.
39 +
40 +Addresses CVE-2021-3781
41 +--- a/base/gdevpipe.c
42 ++++ b/base/gdevpipe.c
43 +@@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access,
44 + #else
45 + gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
46 + gs_fs_list_t *fs = ctx->core->fs;
47 ++ /* The pipe device can be reached in two ways, explicltly with %pipe%
48 ++ or implicitly with "|", so we have to check for both
49 ++ */
50 ++ char f[gp_file_name_sizeof];
51 ++ const char *pipestr = "|";
52 ++ const size_t pipestrlen = strlen(pipestr);
53 ++ const size_t preflen = strlen(iodev->dname);
54 ++ const size_t nlen = strlen(fname);
55 ++ int code1;
56 ++
57 ++ if (preflen + nlen >= gp_file_name_sizeof)
58 ++ return_error(gs_error_invalidaccess);
59 ++
60 ++ memcpy(f, iodev->dname, preflen);
61 ++ memcpy(f + preflen, fname, nlen + 1);
62 ++
63 ++ code1 = gp_validate_path(mem, f, access);
64 ++
65 ++ memcpy(f, pipestr, pipestrlen);
66 ++ memcpy(f + pipestrlen, fname, nlen + 1);
67 +
68 +- if (gp_validate_path(mem, fname, access) != 0)
69 ++ if (code1 != 0 && gp_validate_path(mem, f, access) != 0 )
70 + return gs_error_invalidfileaccess;
71 +
72 + /*
73 +--- a/base/gp_mshdl.c
74 ++++ b/base/gp_mshdl.c
75 +@@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
76 + long hfile; /* Correct for Win32, may be wrong for Win64 */
77 + gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
78 + gs_fs_list_t *fs = ctx->core->fs;
79 ++ char f[gp_file_name_sizeof];
80 ++ const size_t preflen = strlen(iodev->dname);
81 ++ const size_t nlen = strlen(fname);
82 +
83 +- if (gp_validate_path(mem, fname, access) != 0)
84 ++ if (preflen + nlen >= gp_file_name_sizeof)
85 ++ return_error(gs_error_invalidaccess);
86 ++
87 ++ memcpy(f, iodev->dname, preflen);
88 ++ memcpy(f + preflen, fname, nlen + 1);
89 ++
90 ++ if (gp_validate_path(mem, f, access) != 0)
91 + return gs_error_invalidfileaccess;
92 +
93 + /* First we try the open_handle method. */
94 +--- a/base/gp_msprn.c
95 ++++ b/base/gp_msprn.c
96 +@@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
97 + uintptr_t *ptid = &((tid_t *)(iodev->state))->tid;
98 + gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
99 + gs_fs_list_t *fs = ctx->core->fs;
100 ++ const size_t preflen = strlen(iodev->dname);
101 ++ const size_t nlen = strlen(fname);
102 +
103 +- if (gp_validate_path(mem, fname, access) != 0)
104 ++ if (preflen + nlen >= gp_file_name_sizeof)
105 ++ return_error(gs_error_invalidaccess);
106 ++
107 ++ memcpy(pname, iodev->dname, preflen);
108 ++ memcpy(pname + preflen, fname, nlen + 1);
109 ++
110 ++ if (gp_validate_path(mem, pname, access) != 0)
111 + return gs_error_invalidfileaccess;
112 +
113 + /* First we try the open_printer method. */
114 +--- a/base/gp_os2pr.c
115 ++++ b/base/gp_os2pr.c
116 +@@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
117 + FILE ** pfile, char *rfname, uint rnamelen)
118 + {
119 + os2_printer_t *pr = (os2_printer_t *)iodev->state;
120 +- char driver_name[256];
121 ++ char driver_name[gp_file_name_sizeof];
122 + gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
123 + gs_fs_list_t *fs = ctx->core->fs;
124 ++ const size_t preflen = strlen(iodev->dname);
125 ++ const int size_t = strlen(fname);
126 ++
127 ++ if (preflen + nlen >= gp_file_name_sizeof)
128 ++ return_error(gs_error_invalidaccess);
129 ++
130 ++ memcpy(driver_name, iodev->dname, preflen);
131 ++ memcpy(driver_name + preflen, fname, nlen + 1);
132 ++
133 ++ if (gp_validate_path(mem, driver_name, access) != 0)
134 ++ return gs_error_invalidfileaccess;
135 +
136 + /* First we try the open_printer method. */
137 + /* Note that the loop condition here ensures we don't
138 +--- a/base/gslibctx.c
139 ++++ b/base/gslibctx.c
140 +@@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s)
141 + int
142 + gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
143 + {
144 +- char *fp, f[gp_file_name_sizeof];
145 +- const int pipe = 124; /* ASCII code for '|' */
146 +- const int len = strlen(fname);
147 +- int i, code;
148 ++ char f[gp_file_name_sizeof];
149 ++ int code;
150 +
151 + /* Be sure the string copy will fit */
152 +- if (len >= gp_file_name_sizeof)
153 ++ if (strlen(fname) >= gp_file_name_sizeof)
154 + return gs_error_rangecheck;
155 + strcpy(f, fname);
156 +- fp = f;
157 + /* Try to rewrite any %d (or similar) in the string */
158 + rewrite_percent_specifiers(f);
159 +- for (i = 0; i < len; i++) {
160 +- if (f[i] == pipe) {
161 +- fp = &f[i + 1];
162 +- /* Because we potentially have to check file permissions at two levels
163 +- for the output file (gx_device_open_output_file and the low level
164 +- fopen API, if we're using a pipe, we have to add both the full string,
165 +- (including the '|', and just the command to which we pipe - since at
166 +- the pipe_fopen(), the leading '|' has been stripped.
167 +- */
168 +- code = gs_add_control_path(mem, gs_permit_file_writing, f);
169 +- if (code < 0)
170 +- return code;
171 +- code = gs_add_control_path(mem, gs_permit_file_control, f);
172 +- if (code < 0)
173 +- return code;
174 +- break;
175 +- }
176 +- if (!IS_WHITESPACE(f[i]))
177 +- break;
178 +- }
179 +- code = gs_add_control_path(mem, gs_permit_file_control, fp);
180 ++
181 ++ code = gs_add_control_path(mem, gs_permit_file_control, f);
182 + if (code < 0)
183 + return code;
184 +- return gs_add_control_path(mem, gs_permit_file_writing, fp);
185 ++ return gs_add_control_path(mem, gs_permit_file_writing, f);
186 + }
187 +
188 + int
189 + gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
190 + {
191 +- char *fp, f[gp_file_name_sizeof];
192 +- const int pipe = 124; /* ASCII code for '|' */
193 +- const int len = strlen(fname);
194 +- int i, code;
195 ++ char f[gp_file_name_sizeof];
196 ++ int code;
197 +
198 + /* Be sure the string copy will fit */
199 +- if (len >= gp_file_name_sizeof)
200 ++ if (strlen(fname) >= gp_file_name_sizeof)
201 + return gs_error_rangecheck;
202 + strcpy(f, fname);
203 +- fp = f;
204 + /* Try to rewrite any %d (or similar) in the string */
205 +- for (i = 0; i < len; i++) {
206 +- if (f[i] == pipe) {
207 +- fp = &f[i + 1];
208 +- /* Because we potentially have to check file permissions at two levels
209 +- for the output file (gx_device_open_output_file and the low level
210 +- fopen API, if we're using a pipe, we have to add both the full string,
211 +- (including the '|', and just the command to which we pipe - since at
212 +- the pipe_fopen(), the leading '|' has been stripped.
213 +- */
214 +- code = gs_remove_control_path(mem, gs_permit_file_writing, f);
215 +- if (code < 0)
216 +- return code;
217 +- code = gs_remove_control_path(mem, gs_permit_file_control, f);
218 +- if (code < 0)
219 +- return code;
220 +- break;
221 +- }
222 +- if (!IS_WHITESPACE(f[i]))
223 +- break;
224 +- }
225 +- code = gs_remove_control_path(mem, gs_permit_file_control, fp);
226 ++ rewrite_percent_specifiers(f);
227 ++
228 ++ code = gs_remove_control_path(mem, gs_permit_file_control, f);
229 + if (code < 0)
230 + return code;
231 +- return gs_remove_control_path(mem, gs_permit_file_writing, fp);
232 ++ return gs_remove_control_path(mem, gs_permit_file_writing, f);
233 + }
234 +
235 + int
236
237 diff --git a/app-text/ghostscript-gpl/ghostscript-gpl-9.54.0-r1.ebuild b/app-text/ghostscript-gpl/ghostscript-gpl-9.54.0-r1.ebuild
238 new file mode 100644
239 index 00000000000..f494a7875d2
240 --- /dev/null
241 +++ b/app-text/ghostscript-gpl/ghostscript-gpl-9.54.0-r1.ebuild
242 @@ -0,0 +1,191 @@
243 +# Copyright 1999-2021 Gentoo Authors
244 +# Distributed under the terms of the GNU General Public License v2
245 +
246 +EAPI=7
247 +
248 +inherit autotools flag-o-matic toolchain-funcs
249 +
250 +DESCRIPTION="Interpreter for the PostScript language and PDF"
251 +HOMEPAGE="https://ghostscript.com/"
252 +
253 +MY_PN=${PN/-gpl}
254 +MY_P="${MY_PN}-${PV/_}"
255 +PVM=$(ver_cut 1-2)
256 +PVM_S=$(ver_rs 1-2 "")
257 +
258 +MY_PATCHSET="ghostscript-gpl-9.54-patchset-01.tar.xz"
259 +
260 +SRC_URI="https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${PVM_S}/${MY_P}.tar.xz"
261 +
262 +if [[ -n "${MY_PATCHSET}" ]] ; then
263 + SRC_URI+=" https://dev.gentoo.org/~whissi/dist/ghostscript-gpl/${MY_PATCHSET}"
264 +fi
265 +
266 +LICENSE="AGPL-3 CPL-1.0"
267 +SLOT="0/$(ver_cut 1-2)"
268 +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris"
269 +IUSE="cups dbus gtk +jpeg2k l10n_de static-libs unicode X"
270 +
271 +LANGS="ja ko zh-CN zh-TW"
272 +for X in ${LANGS} ; do
273 + IUSE="${IUSE} l10n_${X}"
274 +done
275 +
276 +DEPEND="
277 + app-text/libpaper
278 + media-libs/fontconfig
279 + >=media-libs/freetype-2.4.9:2=
280 + >=media-libs/jbig2dec-0.19:=
281 + >=media-libs/lcms-2.6:2
282 + >=media-libs/libpng-1.6.2:0=
283 + >=media-libs/tiff-4.0.1:0=
284 + >=sys-libs/zlib-1.2.7
285 + virtual/jpeg:0
286 + cups? ( >=net-print/cups-1.3.8 )
287 + dbus? ( sys-apps/dbus )
288 + gtk? ( || ( x11-libs/gtk+:3 x11-libs/gtk+:2 ) )
289 + jpeg2k? ( >=media-libs/openjpeg-2.1.0:2= )
290 + unicode? ( net-dns/libidn:0= )
291 + X? ( x11-libs/libXt x11-libs/libXext )
292 +"
293 +BDEPEND="virtual/pkgconfig"
294 +RDEPEND="${DEPEND}
295 + app-text/poppler-data
296 + >=media-fonts/urw-fonts-2.4.9
297 + l10n_ja? ( media-fonts/kochi-substitute )
298 + l10n_ko? ( media-fonts/baekmuk-fonts )
299 + l10n_zh-CN? ( media-fonts/arphicfonts )
300 + l10n_zh-TW? ( media-fonts/arphicfonts )
301 +"
302 +
303 +S="${WORKDIR}/${MY_P}"
304 +
305 +src_prepare() {
306 + if [[ -n "${MY_PATCHSET}" ]] ; then
307 + # apply various patches, many borrowed from Fedora
308 + # https://src.fedoraproject.org/rpms/ghostscript
309 + # and Debian
310 + # https://salsa.debian.org/printing-team/ghostscript/-/tree/debian/latest/debian/patches
311 + eapply "${WORKDIR}/patches/"*.patch
312 + fi
313 +
314 + eapply "${FILESDIR}"/${P}-CVE-2021-3781.patch
315 +
316 + default
317 +
318 + # remove internal copies of various libraries
319 + rm -r cups/libs || die
320 + rm -r freetype || die
321 + rm -r jbig2dec || die
322 + rm -r jpeg || die
323 + rm -r lcms2mt || die
324 + rm -r libpng || die
325 + rm -r tiff || die
326 + rm -r zlib || die
327 + rm -r openjpeg || die
328 + # remove internal CMaps (CMaps from poppler-data are used instead)
329 + rm -r Resource/CMap || die
330 +
331 + if ! use gtk ; then
332 + sed -e "s:\$(GSSOX)::" \
333 + -e "s:.*\$(GSSOX_XENAME)$::" \
334 + -i base/unix-dll.mak || die "sed failed"
335 + fi
336 +
337 + # Force the include dirs to a neutral location.
338 + sed -e "/^ZLIBDIR=/s:=.*:=${T}:" \
339 + -i configure.ac || die
340 + # Some files depend on zlib.h directly. Redirect them. #573248
341 + # Also make sure to not define OPJ_STATIC to avoid linker errors due to
342 + # hidden symbols (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203327#c1)
343 + sed -e '/^zlib_h/s:=.*:=:' \
344 + -e 's|-DOPJ_STATIC ||' \
345 + -i base/lib.mak || die
346 +
347 + # search path fix
348 + # put LDFLAGS after BINDIR, bug #383447
349 + sed -e "s:\$\(gsdatadir\)/lib:@datarootdir@/ghostscript/${PV}/$(get_libdir):" \
350 + -e "s:exdir=.*:exdir=@datarootdir@/doc/${PF}/examples:" \
351 + -e "s:docdir=.*:docdir=@datarootdir@/doc/${PF}/html:" \
352 + -e "s:GS_DOCDIR=.*:GS_DOCDIR=@datarootdir@/doc/${PF}/html:" \
353 + -e 's:-L$(BINDIR):& $(LDFLAGS):g' \
354 + -i Makefile.in base/*.mak || die "sed failed"
355 +
356 + # remove incorrect symlink, bug 590384
357 + rm ijs/ltmain.sh || die
358 + eautoreconf
359 +
360 + cd ijs || die
361 + eautoreconf
362 +}
363 +
364 +src_configure() {
365 + local FONTPATH
366 + for path in \
367 + "${EPREFIX}"/usr/share/fonts/urw-fonts \
368 + "${EPREFIX}"/usr/share/fonts/Type1 \
369 + "${EPREFIX}"/usr/share/fonts \
370 + "${EPREFIX}"/usr/share/poppler/cMap/Adobe-CNS1 \
371 + "${EPREFIX}"/usr/share/poppler/cMap/Adobe-GB1 \
372 + "${EPREFIX}"/usr/share/poppler/cMap/Adobe-Japan1 \
373 + "${EPREFIX}"/usr/share/poppler/cMap/Adobe-Japan2 \
374 + "${EPREFIX}"/usr/share/poppler/cMap/Adobe-Korea1
375 + do
376 + FONTPATH="$FONTPATH${FONTPATH:+:}${EPREFIX}$path"
377 + done
378 +
379 + PKGCONFIG=$(type -P $(tc-getPKG_CONFIG)) \
380 + econf \
381 + --enable-dynamic \
382 + --enable-freetype \
383 + --enable-fontconfig \
384 + $(use_enable jpeg2k openjpeg) \
385 + --disable-compile-inits \
386 + --with-drivers=ALL \
387 + --with-fontpath="$FONTPATH" \
388 + --with-ijs \
389 + --with-jbig2dec \
390 + --with-libpaper \
391 + --with-system-libtiff \
392 + $(use_enable cups) \
393 + $(use_enable dbus) \
394 + $(use_enable gtk) \
395 + $(use_with cups pdftoraster) \
396 + $(use_with unicode libidn) \
397 + $(use_with X x) \
398 + DARWIN_LDFLAGS_SO_PREFIX="${EPREFIX}/usr/lib/"
399 +
400 + cd "${S}/ijs" || die
401 + econf \
402 + --enable-shared \
403 + $(use_enable static-libs static)
404 +}
405 +
406 +src_compile() {
407 + emake so all
408 +
409 + cd ijs || die
410 + emake
411 +}
412 +
413 +src_install() {
414 + emake DESTDIR="${D}" install-so install
415 +
416 + # move gsc to gs, bug #343447
417 + # gsc collides with gambit, bug #253064
418 + mv -f "${ED}"/usr/bin/{gsc,gs} || die
419 +
420 + cd "${S}/ijs" || die
421 + emake DESTDIR="${D}" install
422 +
423 + # install the CMaps from poppler-data properly, bug #409361
424 + dosym ../../../poppler/cMaps "/usr/share/ghostscript/${PV}/Resource/CMap"
425 +
426 + if ! use static-libs; then
427 + find "${ED}" -name '*.la' -delete || die
428 + fi
429 +
430 + if ! use l10n_de; then
431 + rm -r "${ED}"/usr/share/man/de || die
432 + fi
433 +}