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

Proposed by Julian Taylor
Status: Merged
Merge reported by: Julian Taylor
Merged at revision: not available
Proposed branch: lp:~jtaylor/ubuntu/oneiric/gajim/multiple-CVE
Merge into: lp:ubuntu/oneiric/gajim
Diff against target: 373 lines (+343/-0)
5 files modified
debian/changelog (+19/-0)
debian/patches/CVE-2012-2085.patch (+47/-0)
debian/patches/CVE-2012-2086.patch (+167/-0)
debian/patches/CVE-2012-2093.patch (+107/-0)
debian/patches/series (+3/-0)
To merge this branch: bzr merge lp:~jtaylor/ubuntu/oneiric/gajim/multiple-CVE
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+104266@code.launchpad.net
To post a comment you must log in.
55. By Julian Taylor

fix missing wait on process end

56. By Julian Taylor

change version to ubuntu2

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

Subscribers

People subscribed via source and target branches

to all changes: