[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