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
=== modified file 'debian/changelog'
--- debian/changelog 2011-05-19 12:14:37 +0000
+++ debian/changelog 2012-05-10 20:00:24 +0000
@@ -1,3 +1,22 @@
1gajim (0.14.1-1ubuntu2) oneiric-security; urgency=low
2
3 * SECURITY UPDATE: assisted code execution (LP: #992618)
4 - debian/patches/CVE-2012-2085.dpatch: fix subprocess call to prevent
5 shell escape from via crafted messages
6 https://trac.gajim.org/changeset/bc296e96ac10
7 - CVE-2012-2085
8 * SECURITY UPDATE: sql injection in logging code (LP: #992618)
9 - debian/patches/CVE-2012-2086.dpatch: use a prepated statement
10 https://trac.gajim.org/changeset/bfd5f94489d8
11 - CVE-2012-2086
12 * SECURITY UPDATE: insecure tmpfile creation (LP: #992613)
13 - debian/patches/CVE-2012-2093.dpatch: use safe tmpfile functions
14 when convering LaTeX IM messages to png images
15 Thanks to Nico Golde
16 - CVE-2012-2093
17
18 -- Julian Taylor <jtaylor@ubuntu.com> Tue, 01 May 2012 15:21:25 +0200
19
1gajim (0.14.1-1ubuntu1) oneiric; urgency=low20gajim (0.14.1-1ubuntu1) oneiric; urgency=low
221
3 * Merge from debian unstable(LP: #630876). Remaining changes:22 * Merge from debian unstable(LP: #630876). Remaining changes:
423
=== added file 'debian/patches/CVE-2012-2085.patch'
--- debian/patches/CVE-2012-2085.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/CVE-2012-2085.patch 2012-05-10 20:00:24 +0000
@@ -0,0 +1,47 @@
1Description: prevent assisted code execution CVE-2012-2085
2Origin: https://trac.gajim.org/changeset/bc296e96ac10
3Bug: https://trac.gajim.org/ticket/7031
4Author: Yann Leboulange
5
6--- a/src/common/helpers.py
7+++ b/src/common/helpers.py
8@@ -40,6 +40,7 @@
9 import base64
10 import hashlib
11 import caps_cache
12+import shlex
13
14 from encodings.punycode import punycode_encode
15 from string import Template
16@@ -372,8 +373,18 @@
17 pass
18 return False
19
20-def exec_command(command):
21- subprocess.Popen('%s &' % command, shell=True).wait()
22+def exec_command(command, use_shell=False):
23+ """
24+ execute a command. if use_shell is True, we run the command as is it was
25+ typed in a console. So it may be dangerous if you are not sure about what
26+ is executed.
27+ """
28+ if use_shell:
29+ subprocess.Popen('%s &' % command, shell=True).wait()
30+ else:
31+ args = shlex.split(command.encode('utf-8'))
32+ p = subprocess.Popen(args)
33+ gajim.thread_interface(p.wait)
34
35 def build_command(executable, parameter):
36 # we add to the parameter (can hold path with spaces)
37--- a/src/notify.py
38+++ b/src/notify.py
39@@ -311,7 +311,7 @@
40 command = gajim.config.get_per('notifications', str(advanced_notif_num),
41 'command')
42 try:
43- helpers.exec_command(command)
44+ helpers.exec_command(command, use_shell=True)
45 except Exception:
46 pass
47
048
=== added file 'debian/patches/CVE-2012-2086.patch'
--- debian/patches/CVE-2012-2086.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/CVE-2012-2086.patch 2012-05-10 20:00:24 +0000
@@ -0,0 +1,167 @@
1Description: prevent sql injections CVE-2012-2086
2Origin: https://trac.gajim.org/changeset/988e38ce0e0c
3Bug: https://trac.gajim.org/ticket/7031
4Author: Yann Leboulanger
5
6--- a/src/common/logger.py
7+++ b/src/common/logger.py
8@@ -563,7 +563,7 @@
9 except exceptions.PysqliteOperationalError, e:
10 # Error trying to create a new jid_id. This means there is no log
11 return []
12- where_sql = self._build_contact_where(account, jid)
13+ where_sql, jid_tuple = self._build_contact_where(account, jid)
14
15 now = int(float(time.time()))
16 timed_out = now - (timeout * 60) # before that they are too old
17@@ -571,14 +571,13 @@
18 # 3 - 8 (we avoid the last 2 lines but we still return 5 asked)
19 try:
20 self.cur.execute('''
21- SELECT time, kind, message FROM logs
22- WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d
23- ORDER BY time DESC LIMIT %d OFFSET %d
24- ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV,
25- constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
26- constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR,
27- timed_out, restore_how_many_rows, pending_how_many)
28- )
29+ SELECT time, kind, message FROM logs
30+ WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d
31+ ORDER BY time DESC LIMIT %d OFFSET %d
32+ ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV,
33+ constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
34+ constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, timed_out,
35+ restore_how_many_rows, pending_how_many), jid_tuple)
36
37 results = self.cur.fetchall()
38 except sqlite.DatabaseError:
39@@ -608,18 +607,18 @@
40 except exceptions.PysqliteOperationalError, e:
41 # Error trying to create a new jid_id. This means there is no log
42 return []
43- where_sql = self._build_contact_where(account, jid)
44+ where_sql, jid_tuple = self._build_contact_where(account, jid)
45
46 start_of_day = self.get_unix_time_from_date(year, month, day)
47 seconds_in_a_day = 86400 # 60 * 60 * 24
48 last_second_of_day = start_of_day + seconds_in_a_day - 1
49
50 self.cur.execute('''
51- SELECT contact_name, time, kind, show, message, subject FROM logs
52- WHERE (%s)
53- AND time BETWEEN %d AND %d
54- ORDER BY time
55- ''' % (where_sql, start_of_day, last_second_of_day))
56+ SELECT contact_name, time, kind, show, message, subject FROM logs
57+ WHERE (%s)
58+ AND time BETWEEN %d AND %d
59+ ORDER BY time
60+ ''' % (where_sql, start_of_day, last_second_of_day), jid_tuple)
61
62 results = self.cur.fetchall()
63 return results
64@@ -645,13 +644,13 @@
65 return results
66
67 else: # user just typed something, we search in message column
68- where_sql = self._build_contact_where(account, jid)
69+ where_sql, jid_tuple = self._build_contact_where(account, jid)
70 like_sql = '%' + query.replace("'", "''") + '%'
71 self.cur.execute('''
72- SELECT contact_name, time, kind, show, message, subject FROM logs
73- WHERE (%s) AND message LIKE '%s'
74- ORDER BY time
75- ''' % (where_sql, like_sql))
76+ SELECT contact_name, time, kind, show, message, subject FROM logs
77+ WHERE (%s) AND message LIKE '%s'
78+ ORDER BY time
79+ ''' % (where_sql, like_sql), jid_tuple)
80
81 results = self.cur.fetchall()
82 return results
83@@ -666,7 +665,7 @@
84 # Error trying to create a new jid_id. This means there is no log
85 return []
86 days_with_logs = []
87- where_sql = self._build_contact_where(account, jid)
88+ where_sql, jid_tuple = self._build_contact_where(account, jid)
89
90 # First select all date of month whith logs we want
91 start_of_month = self.get_unix_time_from_date(year, month, 1)
92@@ -678,13 +677,13 @@
93 # and take only one of the same values (distinct)
94 # Now we have timestamps of time 0:00 of every day with logs
95 self.cur.execute('''
96- SELECT DISTINCT time/(86400)*86400 FROM logs
97- WHERE (%s)
98- AND time BETWEEN %d AND %d
99- AND kind NOT IN (%d, %d)
100- ORDER BY time
101- ''' % (where_sql, start_of_month, last_second_of_month,
102- constants.KIND_STATUS, constants.KIND_GCSTATUS))
103+ SELECT DISTINCT time/(86400)*86400 FROM logs
104+ WHERE (%s)
105+ AND time BETWEEN %d AND %d
106+ AND kind NOT IN (%d, %d)
107+ ORDER BY time
108+ ''' % (where_sql, start_of_month, last_second_of_month,
109+ constants.KIND_STATUS, constants.KIND_GCSTATUS), jid_tuple)
110 result = self.cur.fetchall()
111
112 # convert timestamps to day of month
113@@ -700,19 +699,21 @@
114 """
115 where_sql = ''
116 if not is_room:
117- where_sql = self._build_contact_where(account, jid)
118+ where_sql, jid_tuple = self._build_contact_where(account, jid)
119 else:
120 try:
121 jid_id = self.get_jid_id(jid, 'ROOM')
122 except exceptions.PysqliteOperationalError, e:
123 # Error trying to create a new jid_id. This means there is no log
124 return None
125- where_sql = 'jid_id = %s' % jid_id
126+ where_sql = 'jid_id = ?'
127+ jid_tuple = (jid_id,)
128 self.cur.execute('''
129- SELECT MAX(time) FROM logs
130- WHERE (%s)
131- AND kind NOT IN (%d, %d)
132- ''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS))
133+ SELECT MAX(time) FROM logs
134+ WHERE (%s)
135+ AND kind NOT IN (%d, %d)
136+ ''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS),
137+ jid_tuple)
138
139 results = self.cur.fetchone()
140 if results is not None:
141@@ -760,6 +761,7 @@
142 Build the where clause for a jid, including metacontacts jid(s) if any
143 """
144 where_sql = ''
145+ jid_tuple = ()
146 # will return empty list if jid is not associated with
147 # any metacontacts
148 family = gajim.contacts.get_metacontacts_family(account, jid)
149@@ -769,13 +771,15 @@
150 jid_id = self.get_jid_id(user['jid'])
151 except exceptions.PysqliteOperationalError, e:
152 continue
153- where_sql += 'jid_id = %s' % jid_id
154+ where_sql += 'jid_id = ?'
155+ jid_tuple += (jid_id,)
156 if user != family[-1]:
157 where_sql += ' OR '
158 else: # if jid was not associated with metacontacts
159 jid_id = self.get_jid_id(jid)
160- where_sql = 'jid_id = %s' % jid_id
161- return where_sql
162+ where_sql = 'jid_id = ?'
163+ jid_tuple += (jid_id,)
164+ return where_sql, jid_tuple
165
166 def save_transport_type(self, jid, type_):
167 """
0168
=== added file 'debian/patches/CVE-2012-2093.patch'
--- debian/patches/CVE-2012-2093.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/CVE-2012-2093.patch 2012-05-10 20:00:24 +0000
@@ -0,0 +1,107 @@
1Description: fix insecure tmpfile creation CVE-2012-2093
2Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=668710
3Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=668710
4Author: Nico Golde <nion@debian.org>, Julian Taylor <jtaylor@ubuntu.com>
5
6--- a/src/common/latex.py
7+++ b/src/common/latex.py
8@@ -29,7 +29,7 @@
9
10 import os
11 import random
12-from tempfile import gettempdir
13+from tempfile import gettempdir,mkstemp,mkdtemp
14 from subprocess import Popen, PIPE
15
16 import logging
17@@ -57,10 +57,10 @@
18 return True
19 return False
20
21-def get_tmpfile_name():
22+def get_tmpfile_name(tmpdir):
23 random.seed()
24 int_ = random.randint(0, 100)
25- return os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
26+ return os.path.join(tmpdir, 'gajimtex_' + int_.__str__())
27
28 def write_latex(filename, str_):
29 texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
30@@ -78,12 +78,12 @@
31 # a wrapper for Popen so that no window gets opened on Windows
32 # (i think this is the reason we're using Popen rather than just system())
33 # stdout goes to a pipe so that it can be read
34-def popen_nt_friendly(command):
35+def popen_nt_friendly(command, directory):
36 if os.name == 'nt':
37 # CREATE_NO_WINDOW
38- return Popen(command, creationflags=0x08000000, cwd=gettempdir(), stdout=PIPE)
39+ return Popen(command, creationflags=0x08000000, cwd=directory, stdout=PIPE)
40 else:
41- return Popen(command, cwd=gettempdir(), stdout=PIPE)
42+ return Popen(command, cwd=directory, stdout=PIPE)
43
44 def check_for_latex_support():
45 """
46@@ -99,9 +99,9 @@
47 except LatexError:
48 return False
49
50-def try_run(argv):
51+def try_run(argv, directory):
52 try:
53- p = popen_nt_friendly(argv)
54+ p = popen_nt_friendly(argv, directory)
55 out = p.communicate()[0]
56 log.info(out)
57 return p.wait()
58@@ -126,21 +126,28 @@
59 # we triggered the blacklist, immediately return None
60 return None
61
62- tmpfile = get_tmpfile_name()
63+ tmpdir = ""
64+ tmppng = ""
65+ try:
66+ tmpdir = mkdtemp(prefix="gajim")
67+ tmppng = mkstemp(suffix=".png")[1]
68+ except Exception:
69+ raise LatexError("could not securely create one or more temporary files for LaTeX conversion")
70
71+ tmpfile = get_tmpfile_name(tmpdir)
72 # build latex string
73 write_latex(os.path.join(tmpfile + '.tex'), str_)
74
75 # convert TeX to dvi
76 exitcode = try_run(['latex', '--interaction=nonstopmode',
77- tmpfile + '.tex'])
78+ tmpfile + '.tex'], tmpdir)
79
80 if exitcode == 0:
81 # convert dvi to png
82 latex_png_dpi = gajim.config.get('latex_png_dpi')
83 exitcode = try_run(['dvipng', '-bg', bg_str, '-fg', fg_str, '-T',
84 'tight', '-D', latex_png_dpi, tmpfile + '.dvi', '-o',
85- tmpfile + '.png'])
86+ tmpfile + '.png'], tmpdir)
87
88 # remove temp files created by us and TeX
89 extensions = ['.tex', '.log', '.aux', '.dvi']
90@@ -150,10 +157,16 @@
91 except Exception:
92 pass
93
94+ if exitcode == 0:
95+ os.rename(tmpfile + '.png', tmppng)
96+ else:
97+ os.remove(tmppng)
98+
99+ os.rmdir(tmpdir)
100 if isinstance(exitcode, (unicode, str)):
101 raise LatexError(exitcode)
102
103 if exitcode == 0:
104- result = tmpfile + '.png'
105+ result = tmppng
106
107 return result
0108
=== modified file 'debian/patches/series'
--- debian/patches/series 2011-05-19 12:14:37 +0000
+++ debian/patches/series 2012-05-10 20:00:24 +0000
@@ -1,3 +1,6 @@
100_debian-copying.diff100_debian-copying.diff
201_configure-ac.diff201_configure-ac.diff
3debian-changes-0.14.1-1ubuntu13debian-changes-0.14.1-1ubuntu1
4CVE-2012-2085.patch
5CVE-2012-2086.patch
6CVE-2012-2093.patch

Subscribers

People subscribed via source and target branches

to all changes: