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

Michal Schmidt michich at fedoraproject.org
Tue Apr 17 09:13:03 UTC 2012


commit 6ea7a2d0dd1426eff8b2c3b11e77060efc51e684
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-13759-bac8e353d25c.patch |   32 ++++++++
 gajim-0.15-13761-f6f78f3802c0.patch |   26 ++++++
 gajim-0.15-13766-f046e4aaf7d4.patch |  148 +++++++++++++++++++++++++++++++++++
 gajim.spec                          |   13 +++-
 4 files changed, 218 insertions(+), 1 deletions(-)
---
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 16183c7..6e68be3 100644
--- a/gajim.spec
+++ b/gajim.spec
@@ -2,7 +2,7 @@ Summary:	Jabber client written in PyGTK
 Name:		gajim
 %global		majorver 0.15
 Version:	0.15
-Release:	1%{?dist}
+Release:	2%{?dist}
 License:	GPLv3
 Group:		Applications/Internet
 URL:		http://gajim.org/
@@ -49,6 +49,11 @@ BuildRequires:	intltool
 BuildRequires:	pygtk2-devel
 BuildRequires:	hardlink
 
+# 3 patches to fix insecure temp file in the LaTeX plugin
+Patch1:		gajim-0.15-13759-bac8e353d25c.patch
+Patch2:		gajim-0.15-13761-f6f78f3802c0.patch
+Patch3:		gajim-0.15-13766-f046e4aaf7d4.patch
+
 %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.
@@ -56,6 +61,9 @@ Gajim does not require GNOME to run, even though it exists with it nicely.
 
 %prep
 %setup -q
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
 
 %build
 %configure --docdir=%{_docdir}/%{name}-%{version}
@@ -110,6 +118,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{_datadir}/%{name}/src
 
 %changelog
+* Tue Apr 17 2012 Michal Schmidt <mschmidt at redhat.com> 0.15-2
+- CVE-2012-2093 gajim (LaTeX module): Insecure creation of temporary file
+
 * Mon Mar 19 2012 Michal Schmidt <mschmidt at redhat.com> 0.15-1
 - Upstream release 0.15.
 


More information about the scm-commits mailing list