Package: ghostscript Version: 8.63.dfsg.1-2 Severity: normal Tags: patch User: ubuntu-de...@lists.ubuntu.com Usertags: origin-ubuntu maverick ubuntu-patch
*** /tmp/tmpQ4x52y In Ubuntu, we've applied the attached patch to achieve the following: * SECURITY UPDATE: arbitrary code execution via unlimited recursive procedure invocations (LP: #546009) - debian/patches/CVE-2010-1628.dpatch: only initialize structures if all allocations were successful in psi/ialloc.c, psi/idosave.h, psi/isave.c. - CVE-2010-1628 We thought you might be interested in doing the same. -- System Information: Debian Release: squeeze/sid APT prefers maverick-updates APT policy: (500, 'maverick-updates'), (500, 'maverick-security'), (500, 'maverick-proposed'), (500, 'maverick') Architecture: amd64 (x86_64) Kernel: Linux 2.6.35-9-generic (SMP w/2 CPU cores) Locale: LANG=en_CA.utf8, LC_CTYPE=en_CA.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash
diff -u ghostscript-8.71.dfsg.1/debian/changelog ghostscript-8.71.dfsg.1/debian/changelog diff -u ghostscript-8.71.dfsg.1/debian/patches/00list ghostscript-8.71.dfsg.1/debian/patches/00list --- ghostscript-8.71.dfsg.1/debian/patches/00list +++ ghostscript-8.71.dfsg.1/debian/patches/00list @@ -10,0 +11 @@ +CVE-2010-1628 only in patch2: unchanged: --- ghostscript-8.71.dfsg.1.orig/debian/patches/CVE-2010-1628.dpatch +++ ghostscript-8.71.dfsg.1/debian/patches/CVE-2010-1628.dpatch @@ -0,0 +1,133 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +# Description: fix arbitrary code execution via unlimited recursive +# procedure invocations +# Origin: upstream, http://svn.ghostscript.com/viewvc?view=rev&revision=11414 +# Bug: http://bugs.ghostscript.com/show_bug.cgi?id=691295 +# Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ghostscript/+bug/546009 +# Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=584516 + +...@dpatch@ +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' ghostscript-8.71.dfsg.1~/psi/ialloc.c ghostscript-8.71.dfsg.1/psi/ialloc.c +--- ghostscript-8.71.dfsg.1~/psi/ialloc.c 2008-08-28 18:48:19.000000000 -0400 ++++ ghostscript-8.71.dfsg.1/psi/ialloc.c 2010-07-09 08:05:28.000000000 -0400 +@@ -185,7 +185,14 @@ + */ + chunk_t *pcc = mem->pcc; + ref *end; ++ alloc_change_t *cp = 0; ++ int code = 0; + ++ if ((gs_memory_t *)mem != mem->stable_memory) { ++ code = alloc_save_change_alloc(mem, "gs_alloc_ref_array", &cp); ++ if (code < 0) ++ return code; ++ } + obj = gs_alloc_struct_array((gs_memory_t *) mem, num_refs + 1, + ref, &st_refs, cname); + if (obj == 0) +@@ -210,14 +217,10 @@ + chunk_locate_ptr(obj, &cl); + cl.cp->has_refs = true; + } +- if ((gs_memory_t *)mem != mem->stable_memory) { +- ref_packed **ppr = 0; +- int code = alloc_save_change_alloc(mem, "gs_alloc_ref_array", &ppr); +- if (code < 0) +- return code; +- if (ppr) +- *ppr = (ref_packed *)obj; +- } ++ if (cp) { ++ mem->changes = cp; ++ cp->where = (ref_packed *)obj; ++ } + } + make_array(parr, attrs | mem->space, num_refs, obj); + return 0; +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' ghostscript-8.71.dfsg.1~/psi/idosave.h ghostscript-8.71.dfsg.1/psi/idosave.h +--- ghostscript-8.71.dfsg.1~/psi/idosave.h 2008-08-28 18:48:19.000000000 -0400 ++++ ghostscript-8.71.dfsg.1/psi/idosave.h 2010-07-09 08:05:31.000000000 -0400 +@@ -18,6 +18,22 @@ + # define idosave_INCLUDED + + /* ++ * Structure for saved change chain for save/restore. Because of the ++ * garbage collector, we need to distinguish the cases where the change ++ * is in a static object, a dynamic ref, or a dynamic struct. ++ */ ++typedef struct alloc_change_s alloc_change_t; ++struct alloc_change_s { ++ alloc_change_t *next; ++ ref_packed *where; ++ ref contents; ++#define AC_OFFSET_STATIC (-2) /* static object */ ++#define AC_OFFSET_REF (-1) /* dynamic ref */ ++#define AC_OFFSET_ALLOCATED (-3) /* a newly allocated ref array */ ++ short offset; /* if >= 0, offset within struct */ ++}; ++ ++/* + * Save a change that must be undone by restore. We have to pass the + * pointer to the containing object to alloc_save_change for two reasons: + * +@@ -29,6 +45,7 @@ + * relocate the pointer to it from the change record during garbage + * collection. + */ ++ + int alloc_save_change(gs_dual_memory_t *dmem, const ref *pcont, + ref_packed *ptr, client_name_t cname); + int alloc_save_change_in(gs_ref_memory_t *mem, const ref *pcont, +@@ -36,6 +53,6 @@ + /* Remove an AC_OFFSET_ALLOCATED element. */ + void alloc_save_remove(gs_ref_memory_t *mem, ref_packed *obj, client_name_t cname); + /* Allocate a structure for recording an allocation event. */ +-int alloc_save_change_alloc(gs_ref_memory_t *mem, client_name_t cname, ref_packed ***ppr); ++int alloc_save_change_alloc(gs_ref_memory_t *mem, client_name_t cname, alloc_change_t **pcp); + + #endif /* idosave_INCLUDED */ +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' ghostscript-8.71.dfsg.1~/psi/isave.c ghostscript-8.71.dfsg.1/psi/isave.c +--- ghostscript-8.71.dfsg.1~/psi/isave.c 2008-08-28 18:48:19.000000000 -0400 ++++ ghostscript-8.71.dfsg.1/psi/isave.c 2010-07-09 08:05:33.000000000 -0400 +@@ -156,22 +156,6 @@ + /* A link to igcref.c . */ + ptr_proc_reloc(igc_reloc_ref_ptr_nocheck, ref_packed); + +-/* +- * Structure for saved change chain for save/restore. Because of the +- * garbage collector, we need to distinguish the cases where the change +- * is in a static object, a dynamic ref, or a dynamic struct. +- */ +-typedef struct alloc_change_s alloc_change_t; +-struct alloc_change_s { +- alloc_change_t *next; +- ref_packed *where; +- ref contents; +-#define AC_OFFSET_STATIC (-2) /* static object */ +-#define AC_OFFSET_REF (-1) /* dynamic ref */ +-#define AC_OFFSET_ALLOCATED (-3) /* a newly allocated ref array */ +- short offset; /* if >= 0, offset within struct */ +-}; +- + static + CLEAR_MARKS_PROC(change_clear_marks) + { +@@ -519,7 +503,7 @@ + + /* Allocate a structure for recording an allocation event. */ + int +-alloc_save_change_alloc(gs_ref_memory_t *mem, client_name_t cname, ref_packed ***ppr) ++alloc_save_change_alloc(gs_ref_memory_t *mem, client_name_t cname, alloc_change_t **pcp) + { + register alloc_change_t *cp; + +@@ -533,8 +517,7 @@ + cp->where = 0; + cp->offset = AC_OFFSET_ALLOCATED; + make_null(&cp->contents); +- mem->changes = cp; +- *ppr = &cp->where; ++ *pcp = cp; + return 1; + } +