Skip to content

Commit 4e7d0df

Browse files
committed
SECURITY FIX: Prevent code execution through crafted pyc files
When loading a template from an arbitrary file through the AddTemplate() D-Bus method call or DBusTestCase.spawn_server_template() Python method, don't create or use Python's *.pyc cached files.By tricking a user into loading a template from a world-writable directory like /tmp, an attacker could run arbitrary code with the user's privileges by putting a crafted .pyc file into that directory. Note that this is highly unlikely to actually appear in practice as custom dbusmock templates are usually shipped in project directories, not directly in world-writable directories. Thanks to Simon McVittie for discovering this! LP: #1453815 CVE-2015-1326
1 parent a4bd39f commit 4e7d0df

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

NEWS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
0.15.1 (UNRELEASED)
2+
-------------------
3+
- SECURITY FIX: When loading a template from an arbitrary file through the
4+
AddTemplate() D-Bus method call or DBusTestCase.spawn_server_template()
5+
Python method, don't create or use Python's *.pyc cached files. By tricking
6+
a user into loading a template from a world-writable directory like /tmp, an
7+
attacker could run arbitrary code with the user's privileges by putting a
8+
crafted .pyc file into that directory. Note that this is highly unlikely to
9+
actually appear in practice as custom dbusmock templates are usually shipped
10+
in project directories, not directly in world-writable directories.
11+
Thanks to Simon McVittie for discovering this!
12+
(LP: #1453815, CVE-2015-1326)
13+
114
0.15 (2015-05-08)
215
-------------------
316
- NetworkManager template: Restore nm-specific PropertiesChanged signal

dbusmock/mockobject.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import sys
1818
import types
1919
import importlib
20+
import imp
2021
from xml.etree import ElementTree
2122

2223
# we do not use this ourselves, but mock methods often want to use this
@@ -40,14 +41,10 @@
4041

4142
def load_module(name):
4243
if os.path.exists(name) and os.path.splitext(name)[1] == '.py':
43-
sys.path.insert(0, os.path.dirname(os.path.abspath(name)))
44-
try:
45-
m = os.path.splitext(os.path.basename(name))[0]
46-
module = importlib.import_module(m)
47-
finally:
48-
sys.path.pop(0)
49-
50-
return module
44+
mod = imp.new_module(os.path.splitext(os.path.basename(name))[0])
45+
with open(name) as f:
46+
exec(f.read(), mod.__dict__, mod.__dict__)
47+
return mod
5148

5249
return importlib.import_module('dbusmock.templates.' + name)
5350

tests/test_api.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,16 @@ def load(mock, parameters):
592592
self.addCleanup(p_mock.terminate)
593593
self.addCleanup(p_mock.stdout.close)
594594

595+
# ensure that we don't use/write any .pyc files, they are dangerous
596+
# in a world-writable directory like /tmp
597+
self.assertFalse(os.path.exists(my_template.name + 'c'))
598+
try:
599+
from importlib.util import cache_from_source
600+
self.assertFalse(os.path.exists(cache_from_source(my_template.name)))
601+
except ImportError:
602+
# python < 3.4
603+
pass
604+
595605
self.assertEqual(dbus_ultimate.Answer(), 42)
596606

597607
# should appear in introspection

0 commit comments

Comments
 (0)