Merge lp:~jtaylor/ubuntu/natty/gajim/multiple-CVE into lp:ubuntu/natty/gajim
- Natty (11.04)
- multiple-CVE
- Merge into natty
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 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu branches | Pending | ||
Review via email: mp+104265@code.launchpad.net |
Commit message
Description of the change
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 : | # |
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 | + |
Julian, could you please update the status of this merge request so it gets removed from the sponsors list? Thanks.