Merge lp:~jtaylor/ubuntu/natty/gajim/multiple-CVE into lp:ubuntu/natty/gajim

Proposed by Julian Taylor
Status: Merged
Merge reported by: Julian Taylor
Merged at revision: not available
Proposed branch: lp:~jtaylor/ubuntu/natty/gajim/multiple-CVE
Merge into: lp:ubuntu/natty/gajim
Diff against target: 366 lines (+344/-0)
4 files modified
debian/changelog (+19/-0)
debian/patches/CVE-2012-2085.patch (+54/-0)
debian/patches/CVE-2012-2086.patch (+157/-0)
debian/patches/CVE-2012-2093.patch (+114/-0)
To merge this branch: bzr merge lp:~jtaylor/ubuntu/natty/gajim/multiple-CVE
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+104265@code.launchpad.net
To post a comment you must log in.
56. By Julian Taylor

fix missing jid tuple in patch

57. By Julian Taylor

fix missing wait on process end

Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Julian, could you please update the status of this merge request so it gets removed from the sponsors list? Thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2010-12-08 15:02:54 +0000
3+++ debian/changelog 2012-05-10 19:53:18 +0000
4@@ -1,3 +1,22 @@
5+gajim (0.13.4-3ubuntu2.11.04.1) natty-security; urgency=low
6+
7+ * SECURITY UPDATE: assisted code execution (LP: #992618)
8+ - debian/patches/CVE-2012-2085.dpatch: fix subprocess call to prevent
9+ shell escape from via crafted messages
10+ https://trac.gajim.org/changeset/bc296e96ac10
11+ - CVE-2012-2085
12+ * SECURITY UPDATE: sql injection in logging code (LP: #992618)
13+ - debian/patches/CVE-2012-2086.dpatch: use a prepated statement
14+ https://trac.gajim.org/changeset/bfd5f94489d8
15+ - CVE-2012-2086
16+ * SECURITY UPDATE: insecure tmpfile creation (LP: #992613)
17+ - debian/patches/CVE-2012-2093.dpatch: use safe tmpfile functions
18+ when convering LaTeX IM messages to png images
19+ Thanks to Nico Golde
20+ - CVE-2012-2093
21+
22+ -- Julian Taylor <jtaylor@ubuntu.com> Tue, 01 May 2012 15:21:25 +0200
23+
24 gajim (0.13.4-3ubuntu2) natty; urgency=low
25
26 * Rebuild with python 2.7 as the python default.
27
28=== added file 'debian/patches/CVE-2012-2085.patch'
29--- debian/patches/CVE-2012-2085.patch 1970-01-01 00:00:00 +0000
30+++ debian/patches/CVE-2012-2085.patch 2012-05-10 19:53:18 +0000
31@@ -0,0 +1,54 @@
32+#! /bin/sh /usr/share/dpatch/dpatch-run
33+## Description: prevent assisted code execution CVE-2012-2085
34+## Origin: https://trac.gajim.org/changeset/bc296e96ac10
35+## Bug: https://trac.gajim.org/ticket/7031
36+## CVE-2012-2085.dpatch by Julian Taylor <jtaylor@ubuntu.com>
37+##
38+## All lines beginning with `## DP:' are a description of the patch.
39+## DP: No description.
40+
41+@DPATCH@
42+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gajim-lucid.orig~/src/common/helpers.py gajim-lucid.orig/src/common/helpers.py
43+--- gajim-lucid.orig~/src/common/helpers.py 2012-05-01 15:19:52.000000000 +0200
44++++ gajim-lucid.orig/src/common/helpers.py 2012-05-01 15:20:49.347118151 +0200
45+@@ -39,6 +39,7 @@
46+ import base64
47+ import sys
48+ import hashlib
49++import shlex
50+
51+ from encodings.punycode import punycode_encode
52+
53+@@ -355,8 +356,18 @@
54+ pass
55+ return False
56+
57+-def exec_command(command):
58+- subprocess.Popen('%s &' % command, shell=True).wait()
59++def exec_command(command, use_shell=False):
60++ """
61++ execute a command. if use_shell is True, we run the command as is it was
62++ typed in a console. So it may be dangerous if you are not sure about what
63++ is executed.
64++ """
65++ if use_shell:
66++ subprocess.Popen('%s &' % command, shell=True).wait()
67++ else:
68++ args = shlex.split(command.encode('utf-8'))
69++ p = subprocess.Popen(args)
70++ gajim.thread_interface(p.wait)
71+
72+ def build_command(executable, parameter):
73+ # we add to the parameter (can hold path with spaces)
74+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gajim-lucid.orig~/src/notify.py gajim-lucid.orig/src/notify.py
75+--- gajim-lucid.orig~/src/notify.py 2012-05-01 15:19:52.000000000 +0200
76++++ gajim-lucid.orig/src/notify.py 2012-05-01 15:21:18.347117755 +0200
77+@@ -323,7 +323,7 @@
78+ command = gajim.config.get_per('notifications', str(advanced_notif_num),
79+ 'command')
80+ try:
81+- helpers.exec_command(command)
82++ helpers.exec_command(command, use_shell=True)
83+ except Exception:
84+ pass
85+
86
87=== added file 'debian/patches/CVE-2012-2086.patch'
88--- debian/patches/CVE-2012-2086.patch 1970-01-01 00:00:00 +0000
89+++ debian/patches/CVE-2012-2086.patch 2012-05-10 19:53:18 +0000
90@@ -0,0 +1,157 @@
91+#! /bin/sh /usr/share/dpatch/dpatch-run
92+## Description: prevent sql injections CVE-2012-2086
93+## Origin: https://trac.gajim.org/changeset/bc296e96ac10
94+## Bug: https://trac.gajim.org/ticket/7031
95+## CVE-2012-2086.dpatch by Julian Taylor <jtaylor@ubuntu.com>
96+##
97+## All lines beginning with `## DP:' are a description of the patch.
98+## DP: No description.
99+
100+@DPATCH@
101+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gajim-lucid.orig~/src/common/logger.py gajim-lucid.orig/src/common/logger.py
102+--- gajim-lucid.orig~/src/common/logger.py 2012-05-01 15:19:52.000000000 +0200
103++++ gajim-lucid.orig/src/common/logger.py 2012-05-01 15:23:03.891116311 +0200
104+@@ -527,7 +527,7 @@
105+ except exceptions.PysqliteOperationalError, e:
106+ # Error trying to create a new jid_id. This means there is no log
107+ return []
108+- where_sql = self._build_contact_where(account, jid)
109++ where_sql, jid_tuple = self._build_contact_where(account, jid)
110+
111+ now = int(float(time.time()))
112+ timed_out = now - (timeout * 60) # before that they are too old
113+@@ -539,10 +539,9 @@
114+ WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d
115+ ORDER BY time DESC LIMIT %d OFFSET %d
116+ ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV,
117+- constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
118+- constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR,
119+- timed_out, restore_how_many_rows, pending_how_many)
120+- )
121++ constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
122++ constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, timed_out,
123++ restore_how_many_rows, pending_how_many), jid_tuple)
124+
125+ results = self.cur.fetchall()
126+ except sqlite.DatabaseError:
127+@@ -569,7 +568,7 @@
128+ except exceptions.PysqliteOperationalError, e:
129+ # Error trying to create a new jid_id. This means there is no log
130+ return []
131+- where_sql = self._build_contact_where(account, jid)
132++ where_sql, jid_tuple = self._build_contact_where(account, jid)
133+
134+ start_of_day = self.get_unix_time_from_date(year, month, day)
135+ seconds_in_a_day = 86400 # 60 * 60 * 24
136+@@ -580,7 +579,7 @@
137+ WHERE (%s)
138+ AND time BETWEEN %d AND %d
139+ ORDER BY time
140+- ''' % (where_sql, start_of_day, last_second_of_day))
141++ ''' % (where_sql, start_of_day, last_second_of_day), jid_tuple)
142+
143+ results = self.cur.fetchall()
144+ return results
145+@@ -603,13 +602,13 @@
146+ return results
147+
148+ else: # user just typed something, we search in message column
149+- where_sql = self._build_contact_where(account, jid)
150++ where_sql, jid_tuple = self._build_contact_where(account, jid)
151+ like_sql = '%' + query.replace("'", "''") + '%'
152+ self.cur.execute('''
153+ SELECT contact_name, time, kind, show, message, subject FROM logs
154+ WHERE (%s) AND message LIKE '%s'
155+ ORDER BY time
156+- ''' % (where_sql, like_sql))
157++ ''' % (where_sql, like_sql), jid_tuple)
158+
159+ results = self.cur.fetchall()
160+ return results
161+@@ -622,7 +621,7 @@
162+ # Error trying to create a new jid_id. This means there is no log
163+ return []
164+ days_with_logs = []
165+- where_sql = self._build_contact_where(account, jid)
166++ where_sql, jid_tuple = self._build_contact_where(account, jid)
167+
168+ # First select all date of month whith logs we want
169+ start_of_month = self.get_unix_time_from_date(year, month, 1)
170+@@ -640,7 +639,7 @@
171+ AND kind NOT IN (%d, %d)
172+ ORDER BY time
173+ ''' % (where_sql, start_of_month, last_second_of_month,
174+- constants.KIND_STATUS, constants.KIND_GCSTATUS))
175++ constants.KIND_STATUS, constants.KIND_GCSTATUS), jid_tuple)
176+ result = self.cur.fetchall()
177+
178+ # convert timestamps to day of month
179+@@ -654,19 +653,21 @@
180+ we had logs (excluding statuses)'''
181+ where_sql = ''
182+ if not is_room:
183+- where_sql = self._build_contact_where(account, jid)
184++ where_sql, jid_tuple = self._build_contact_where(account, jid)
185+ else:
186+ try:
187+ jid_id = self.get_jid_id(jid, 'ROOM')
188+ except exceptions.PysqliteOperationalError, e:
189+ # Error trying to create a new jid_id. This means there is no log
190+ return None
191+- where_sql = 'jid_id = %s' % jid_id
192++ where_sql = 'jid_id = ?'
193++ jid_tuple = (jid_id,)
194+ self.cur.execute('''
195+ SELECT MAX(time) FROM logs
196+ WHERE (%s)
197+ AND kind NOT IN (%d, %d)
198+- ''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS))
199++ ''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS),
200++ jid_tuple)
201+
202+ results = self.cur.fetchone()
203+ if results is not None:
204+@@ -683,11 +684,13 @@
205+ except exceptions.PysqliteOperationalError, e:
206+ # Error trying to create a new jid_id. This means there is no log
207+ return None
208+- where_sql = 'jid_id = %s' % jid_id
209++ where_sql = 'jid_id = ?'
210++ jid_tuple = (jid_id,)
211++
212+ self.cur.execute('''
213+ SELECT time FROM rooms_last_message_time
214+ WHERE (%s)
215+- ''' % (where_sql))
216++ ''' % (where_sql), jid_tuple)
217+
218+ results = self.cur.fetchone()
219+ if results is not None:
220+@@ -709,6 +712,7 @@
221+ '''build the where clause for a jid, including metacontacts
222+ jid(s) if any'''
223+ where_sql = ''
224++ jid_tuple = ()
225+ # will return empty list if jid is not associated with
226+ # any metacontacts
227+ family = gajim.contacts.get_metacontacts_family(account, jid)
228+@@ -718,13 +722,15 @@
229+ jid_id = self.get_jid_id(user['jid'])
230+ except exceptions.PysqliteOperationalError, e:
231+ continue
232+- where_sql += 'jid_id = %s' % jid_id
233++ where_sql += 'jid_id = ?'
234++ jid_tuple += (jid_id,)
235+ if user != family[-1]:
236+ where_sql += ' OR '
237+ else: # if jid was not associated with metacontacts
238+ jid_id = self.get_jid_id(jid)
239+- where_sql = 'jid_id = %s' % jid_id
240+- return where_sql
241++ where_sql = 'jid_id = ?'
242++ jid_tuple += (jid_id,)
243++ return where_sql,jid_tuple
244+
245+ def save_transport_type(self, jid, type_):
246+ '''save the type of the transport in DB'''
247+
248
249=== added file 'debian/patches/CVE-2012-2093.patch'
250--- debian/patches/CVE-2012-2093.patch 1970-01-01 00:00:00 +0000
251+++ debian/patches/CVE-2012-2093.patch 2012-05-10 19:53:18 +0000
252@@ -0,0 +1,114 @@
253+#! /bin/sh /usr/share/dpatch/dpatch-run
254+## Description: fix insecure tmpfile creation CVE-2012-2093
255+## Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=668710
256+## Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=668710
257+## CVE-2012-2093.dpatch by Julian Taylor <jtaylor@ubuntu.com>
258+##
259+## All lines beginning with `## DP:' are a description of the patch.
260+## DP: No description.
261+
262+@DPATCH@
263+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' gajim-lucid.orig~/src/common/latex.py gajim-lucid.orig/src/common/latex.py
264+--- gajim-lucid.orig~/src/common/latex.py 2012-05-01 15:19:52.000000000 +0200
265++++ gajim-lucid.orig/src/common/latex.py 2012-05-01 15:26:22.031113594 +0200
266+@@ -29,7 +29,7 @@
267+
268+ import os
269+ import random
270+-from tempfile import gettempdir
271++from tempfile import gettempdir,mkstemp,mkdtemp
272+ from subprocess import Popen, PIPE
273+
274+ import logging
275+@@ -57,10 +57,10 @@
276+ return True
277+ return False
278+
279+-def get_tmpfile_name():
280++def get_tmpfile_name(tmpdir):
281+ random.seed()
282+ int_ = random.randint(0, 100)
283+- return os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
284++ return os.path.join(tmpdir, 'gajimtex_' + int_.__str__())
285+
286+ def write_latex(filename, str_):
287+ texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
288+@@ -78,12 +78,12 @@
289+ # a wrapper for Popen so that no window gets opened on Windows
290+ # (i think this is the reason we're using Popen rather than just system())
291+ # stdout goes to a pipe so that it can be read
292+-def popen_nt_friendly(command):
293++def popen_nt_friendly(command, directory):
294+ if os.name == 'nt':
295+ # CREATE_NO_WINDOW
296+- return Popen(command, creationflags=0x08000000, cwd=gettempdir(), stdout=PIPE)
297++ return Popen(command, creationflags=0x08000000, cwd=directory, stdout=PIPE)
298+ else:
299+- return Popen(command, cwd=gettempdir(), stdout=PIPE)
300++ return Popen(command, cwd=directory, stdout=PIPE)
301+
302+ def check_for_latex_support():
303+ '''check is latex is available and if it can create a picture.'''
304+@@ -98,9 +98,9 @@
305+ except LatexError:
306+ return False
307+
308+-def try_run(argv):
309++def try_run(argv, directory):
310+ try:
311+- p = popen_nt_friendly(argv)
312++ p = popen_nt_friendly(argv, directory)
313+ out = p.communicate()[0]
314+ log.info(out)
315+ return p.wait()
316+@@ -125,21 +125,28 @@
317+ # we triggered the blacklist, immediately return None
318+ return None
319+
320+- tmpfile = get_tmpfile_name()
321++ tmpdir = ""
322++ tmppng = ""
323++ try:
324++ tmpdir = mkdtemp(prefix="gajim")
325++ tmppng = mkstemp(suffix=".png")[1]
326++ except Exception:
327++ raise LatexError("could not securely create one or more temporary files for LaTeX conversion")
328+
329++ tmpfile = get_tmpfile_name(tmpdir)
330+ # build latex string
331+ write_latex(os.path.join(tmpfile + '.tex'), str_)
332+
333+ # convert TeX to dvi
334+ exitcode = try_run(['latex', '--interaction=nonstopmode',
335+- tmpfile + '.tex'])
336++ tmpfile + '.tex'], tmpdir)
337+
338+ if exitcode == 0:
339+ # convert dvi to png
340+ latex_png_dpi = gajim.config.get('latex_png_dpi')
341+ exitcode = try_run(['dvipng', '-bg', bg_str, '-fg', fg_str, '-T',
342+ 'tight', '-D', latex_png_dpi, tmpfile + '.dvi', '-o',
343+- tmpfile + '.png'])
344++ tmpfile + '.png'], tmpdir)
345+
346+ # remove temp files created by us and TeX
347+ extensions = ['.tex', '.log', '.aux', '.dvi']
348+@@ -149,11 +156,17 @@
349+ except Exception:
350+ pass
351+
352++ if exitcode == 0:
353++ os.rename(tmpfile + '.png', tmppng)
354++ else:
355++ os.remove(tmppng)
356++
357++ os.rmdir(tmpdir)
358+ if isinstance(exitcode, (unicode, str)):
359+ raise LatexError(exitcode)
360+
361+ if exitcode == 0:
362+- result = tmpfile + '.png'
363++ result = tmppng
364+
365+ return result
366+

Subscribers

People subscribed via source and target branches

to all changes: