[gajim/el6] CVE-2012-2093 gajim (LaTeX module): Insecure creation of temporary file

Michal Schmidt michich at fedoraproject.org
Tue Apr 17 09:44:21 UTC 2012


commit 43056b399eec0929827d684334204a522d1814bf
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Apr 17 11:03:06 2012 +0200

    CVE-2012-2093 gajim (LaTeX module): Insecure creation of temporary file

 gajim-0.15-12438.patch              |   86 ++++++++++++++++++++
 gajim-0.15-13759-bac8e353d25c.patch |   32 ++++++++
 gajim-0.15-13761-f6f78f3802c0.patch |   26 ++++++
 gajim-0.15-13766-f046e4aaf7d4.patch |  148 +++++++++++++++++++++++++++++++++++
 gajim.spec                          |   17 ++++-
 5 files changed, 308 insertions(+), 1 deletions(-)
---
diff --git a/gajim-0.15-12438.patch b/gajim-0.15-12438.patch
new file mode 100644
index 0000000..c8f97b3
--- /dev/null
+++ b/gajim-0.15-12438.patch
@@ -0,0 +1,86 @@
+# HG changeset patch
+# User Yann Leboulanger <asterix at lagaule.org>
+# Date 1285362921 -7200
+# Node ID c821dd3af25fdd8b534b2fa2e39dd9f6068517a3
+# Parent  e81ceeabe85a44ebb07fe493bd4482f2e32c4d7d
+[Zhihao Yuan & I] use convert is dvipng doesn't work. Fixes #5935
+
+diff --git a/src/common/latex.py b/src/common/latex.py
+--- a/src/common/latex.py
++++ b/src/common/latex.py
+@@ -115,11 +115,16 @@
+     result = None
+     exitcode = 0
+ 
+-    try:
+-        bg_str, fg_str = gajim.interface.get_bg_fg_colors()
+-    except:
+-        # interface may not be available when we test latext at startup
+-        bg_str, fg_str = 'rgb 1.0 1.0 1.0', 'rgb 0.0 0.0 0.0'
++    def fg_str(fmt):
++        try:
++            return [{'hex' : '+level-colors', 'tex' : '-fg'}[fmt],
++                gajim.interface.get_fg_color(fmt)]
++        except KeyError:
++            # interface may not be available when we test latex at startup
++            return []
++        except AttributeError:
++            # interface may not be available when we test latext at startup
++            return ['-fg', 'rgb 0.0 0.0 0.0']
+ 
+     # filter latex code with bad commands
+     if check_blacklist(str_):
+@@ -138,9 +143,13 @@
+     if exitcode == 0:
+         # convert dvi to png
+         latex_png_dpi = gajim.config.get('latex_png_dpi')
+-        exitcode = try_run(['dvipng', '-bg', bg_str, '-fg', fg_str, '-T',
+-                        'tight', '-D', latex_png_dpi, tmpfile + '.dvi', '-o',
+-                        tmpfile + '.png'])
++        exitcode = try_run(['dvipng'] + fg_str('tex') + ['-T', 'tight', '-D',
++            latex_png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'])
++
++        if exitcode:
++            # dvipng failed, try convert
++            exitcode = try_run(['convert'] + fg_str('hex') + ['-trim',
++                '-density', latex_png_dpi, tmpfile + '.dvi', tmpfile + '.png'])
+ 
+     # remove temp files created by us and TeX
+     extensions = ['.tex', '.log', '.aux', '.dvi']
+diff --git a/src/features_window.py b/src/features_window.py
+--- a/src/features_window.py
++++ b/src/features_window.py
+@@ -92,8 +92,8 @@
+                         _('Requires python2.5.')),
+                 _('LaTeX'): (self.latex_available,
+                         _('Transform LaTeX expressions between $$ $$.'),
+-                        _('Requires texlive-latex-base and dvipng. You have to set \'use_latex\' to True in the Advanced Configuration Editor.'),
+-                        _('Requires texlive-latex-base and dvipng (All is in MikTeX). You have to set \'use_latex\' to True in the Advanced Configuration Editor.')),
++                        _('Requires texlive-latex-base and (dvipng or ImageMagick). You have to set \'use_latex\' to True in the Advanced Configuration Editor.'),
++                        _('Requires texlive-latex-base and (dvipng or ImageMagick) (All is in MikTeX). You have to set \'use_latex\' to True in the Advanced Configuration Editor.')),
+                 _('End to End message encryption'): (self.pycrypto_available,
+                         _('Encrypting chat messages.'),
+                         _('Requires python-crypto.'),
+diff --git a/src/gui_interface.py b/src/gui_interface.py
+--- a/src/gui_interface.py
++++ b/src/gui_interface.py
+@@ -2704,6 +2704,19 @@
+         fg_str = format_gdkcolor(style.text[gtk.STATE_NORMAL])
+         return (bg_str, fg_str)
+ 
++    def get_fg_color(self, fmt='hex'):
++        def format_gdkcolor (c):
++            if fmt == 'tex':
++                return ' '.join([str(s) for s in 
++                    ('rgb', c.red_float, c.green_float, c.blue_float)])
++            elif fmt == 'hex':
++                return str(c)
++
++        # get foreground style color and create string
++        dummy = gtk.Invisible()
++        dummy.ensure_style()
++        return format_gdkcolor(dummy.get_style().text[gtk.STATE_NORMAL])
++
+     def read_sleepy(self):
+         """
+         Check idle status and change that status if needed
diff --git a/gajim-0.15-13759-bac8e353d25c.patch b/gajim-0.15-13759-bac8e353d25c.patch
new file mode 100644
index 0000000..a8d30ca
--- /dev/null
+++ b/gajim-0.15-13759-bac8e353d25c.patch
@@ -0,0 +1,32 @@
+# HG changeset patch
+# User Yann Leboulanger <asterix at lagaule.org>
+# Date 1334071532 -7200
+# Node ID bac8e353d25c7196f2635ef7c2b2e479f6818fab
+# Parent  a360737332cd0135df68fb212e6156931ebab312
+improve temp file search when using latex to prevent overwriting files
+
+diff --git a/src/common/latex.py b/src/common/latex.py
+--- a/src/common/latex.py
++++ b/src/common/latex.py
+@@ -59,8 +59,19 @@
+ 
+ def get_tmpfile_name():
+     random.seed()
+-    int_ = random.randint(0, 100)
+-    return os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
++    while(nb < 100):
++        int_ = random.randint(0, 10000)
++        filename = os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
++        # Check if a file to not overwrite it
++        ok = True
++        extensions = ['.tex', '.log', '.aux', '.dvi']
++        for ext in extensions:
++            if os.path.exists(filename + ext):
++                ok = False
++                break
++        if ok:
++            return filename
++    return filename
+ 
+ def write_latex(filename, str_):
+     texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
diff --git a/gajim-0.15-13761-f6f78f3802c0.patch b/gajim-0.15-13761-f6f78f3802c0.patch
new file mode 100644
index 0000000..5d87423
--- /dev/null
+++ b/gajim-0.15-13761-f6f78f3802c0.patch
@@ -0,0 +1,26 @@
+# HG changeset patch
+# User Yann Leboulanger <asterix at lagaule.org>
+# Date 1334207870 -7200
+# Node ID f6f78f3802c07736cb63b3e696778dabe8263cbb
+# Parent  ab4f06e5e024b0e1bb1aab3d4ec5f8a39c5d32aa
+fix a loop. Fixes #7142
+
+diff --git a/src/common/latex.py b/src/common/latex.py
+--- a/src/common/latex.py
++++ b/src/common/latex.py
+@@ -59,6 +59,7 @@
+ 
+ def get_tmpfile_name():
+     random.seed()
++    nb = 0
+     while(nb < 100):
+         int_ = random.randint(0, 10000)
+         filename = os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
+@@ -71,6 +72,7 @@
+                 break
+         if ok:
+             return filename
++        nb += 1
+     return filename
+ 
+ def write_latex(filename, str_):
diff --git a/gajim-0.15-13766-f046e4aaf7d4.patch b/gajim-0.15-13766-f046e4aaf7d4.patch
new file mode 100644
index 0000000..5eb6787
--- /dev/null
+++ b/gajim-0.15-13766-f046e4aaf7d4.patch
@@ -0,0 +1,148 @@
+# HG changeset patch
+# User Yann Leboulanger <asterix at lagaule.org>
+# Date 1334652355 -7200
+# Node ID f046e4aaf7d49b2934622db66da1667ddddb1703
+# Parent  0a8585330ccaa26f97ead998c29427d31c5d395b
+more secure tmp file creation for latex
+
+diff --git a/src/common/latex.py b/src/common/latex.py
+--- a/src/common/latex.py
++++ b/src/common/latex.py
+@@ -29,7 +29,7 @@
+ 
+ import os
+ import random
+-from tempfile import gettempdir
++from tempfile import mkstemp, mkdtemp
+ from subprocess import Popen, PIPE
+ 
+ import logging
+@@ -57,24 +57,6 @@
+             return True
+     return False
+ 
+-def get_tmpfile_name():
+-    random.seed()
+-    nb = 0
+-    while(nb < 100):
+-        int_ = random.randint(0, 10000)
+-        filename = os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
+-        # Check if a file to not overwrite it
+-        ok = True
+-        extensions = ['.tex', '.log', '.aux', '.dvi']
+-        for ext in extensions:
+-            if os.path.exists(filename + ext):
+-                ok = False
+-                break
+-        if ok:
+-            return filename
+-        nb += 1
+-    return filename
+-
+ def write_latex(filename, str_):
+     texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
+     texstr += '\\usepackage{amsmath}\\usepackage{amssymb}'
+@@ -91,12 +73,13 @@
+ # a wrapper for Popen so that no window gets opened on Windows
+ # (i think this is the reason we're using Popen rather than just system())
+ # stdout goes to a pipe so that it can be read
+-def popen_nt_friendly(command):
++def popen_nt_friendly(command, directory):
+     if os.name == 'nt':
+         # CREATE_NO_WINDOW
+-        return Popen(command, creationflags=0x08000000, cwd=gettempdir(), stdout=PIPE)
++        return Popen(command, creationflags=0x08000000, cwd=directory,
++            stdout=PIPE)
+     else:
+-        return Popen(command, cwd=gettempdir(), stdout=PIPE)
++        return Popen(command, cwd=directory, stdout=PIPE)
+ 
+ def check_for_latex_support():
+     """
+@@ -112,16 +95,16 @@
+     except LatexError:
+         return False
+ 
+-def try_run(argv):
++def try_run(argv, directory):
+     try:
+-        p = popen_nt_friendly(argv)
++        p = popen_nt_friendly(argv, directory)
+         out = p.communicate()[0]
+         log.info(out)
+         return p.wait()
+     except Exception, e:
+         return _('Error executing "%(command)s": %(error)s') % {
+-                'command': " ".join(argv),
+-                'error': helpers.decode_string(str(e))}
++            'command': " ".join(argv),
++            'error': helpers.decode_string(str(e))}
+ 
+ 
+ def latex_to_image(str_):
+@@ -137,32 +120,41 @@
+             return []
+         except AttributeError:
+             # interface may not be available when we test latext at startup
+-            return ['-fg', 'rgb 0.0 0.0 0.0']
++            return {'hex': ['+level-colors', '0x000000'],
++                'tex': ['-fg', 'rgb 0.0 0.0 0.0']}[fmt]
+ 
+     # filter latex code with bad commands
+     if check_blacklist(str_):
+         # we triggered the blacklist, immediately return None
+         return None
+ 
+-    tmpfile = get_tmpfile_name()
++    try:
++        tmpdir = mkdtemp(prefix='gajimtex')
++        tmppng = mkstemp(prefix='gajim_tex', suffix='.png')[1]
++    except Exception:
++        raise LatexError('could not securely create one or more temporary files'
++            ' for LaTeX conversion')
++
++    tmpfile = os.path.join(tmpdir, 'gajim_tex')
+ 
+     # build latex string
+-    write_latex(os.path.join(tmpfile + '.tex'), str_)
++    write_latex(tmpfile + '.tex', str_)
+ 
+     # convert TeX to dvi
+-    exitcode = try_run(['latex', '--interaction=nonstopmode',
+-                      tmpfile + '.tex'])
++    exitcode = try_run(['latex', '--interaction=nonstopmode', tmpfile + '.tex'],
++        tmpdir)
+ 
+     if exitcode == 0:
+         # convert dvi to png
+         latex_png_dpi = gajim.config.get('latex_png_dpi')
+         exitcode = try_run(['dvipng'] + fg_str('tex') + ['-T', 'tight', '-D',
+-            latex_png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'])
++            latex_png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'], tmpdir)
+ 
+         if exitcode:
+             # dvipng failed, try convert
+             exitcode = try_run(['convert'] + fg_str('hex') + ['-trim',
+-                '-density', latex_png_dpi, tmpfile + '.dvi', tmpfile + '.png'])
++                '-density', latex_png_dpi, tmpfile + '.dvi', tmpfile + '.png'],
++                tmpdir)
+ 
+     # remove temp files created by us and TeX
+     extensions = ['.tex', '.log', '.aux', '.dvi']
+@@ -172,10 +164,15 @@
+         except Exception:
+             pass
+ 
++    if exitcode == 0:
++        os.rename(tmpfile + '.png', tmppng)
++
++    os.rmdir(tmpdir)
++
+     if isinstance(exitcode, (unicode, str)):
+         raise LatexError(exitcode)
+ 
+     if exitcode == 0:
+-        result = tmpfile + '.png'
++        result = tmppng
+ 
+     return result
diff --git a/gajim.spec b/gajim.spec
index a942ea0..df3d933 100644
--- a/gajim.spec
+++ b/gajim.spec
@@ -9,7 +9,13 @@ URL:		http://gajim.org/
 Source0:	http://gajim.org/downloads/%{majorver}/%{name}-%{version}.tar.bz2
 # libasyncns triggers a kernel bug (RHBZ#529202), so let's not use it until
 # it's fixed.
-Patch2:		gajim-0.14-disable-libasyncns.patch
+Patch1:		gajim-0.14-disable-libasyncns.patch
+# 4 patches to fix insecure temp file in the LaTeX plugin
+Patch2:		gajim-0.15-12438.patch
+Patch3:		gajim-0.15-13759-bac8e353d25c.patch
+Patch4:		gajim-0.15-13761-f6f78f3802c0.patch
+Patch5:		gajim-0.15-13766-f046e4aaf7d4.patch
+
 BuildArch:	noarch
 BuildRoot:	%(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
@@ -56,6 +62,7 @@ BuildRequires:	intltool
 BuildRequires:	pygtk2-devel
 BuildRequires:	hardlink
 
+
 %description
 Gajim is a Jabber client written in PyGTK. The goal of Gajim's developers is
 to provide a full featured and easy to use xmpp client for the GTK+ users.
@@ -63,7 +70,11 @@ Gajim does not require GNOME to run, even though it exists with it nicely.
 
 %prep
 %setup -q
+%patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
 
 %build
 %configure --docdir=%{_docdir}/%{name}-%{version}
@@ -121,6 +132,10 @@ rm -rf %{buildroot}
 %{_datadir}/%{name}/src
 
 %changelog
+* Tue Apr 17 2012 Michal Schmidt <mschmidt at redhat.com> 0.14.4-1
+- Update to 0.14.4.
+- Apply fix for CVE-2012-2093.
+
 * Fri Feb 25 2011 Michal Schmidt <mschmidt at redhat.com> 0.14.1-3.el6.1
 - python-kerberos is not available in RHEL6.0.
 


More information about the scm-commits mailing list