Skip to content

Commit

Permalink
SECURITY FIX: Prevent code execution through crafted pyc files
Browse files Browse the repository at this point in the history
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
  • Loading branch information
martinpitt committed May 12, 2015
1 parent a4bd39f commit 4e7d0df
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
13 changes: 13 additions & 0 deletions NEWS
@@ -1,3 +1,16 @@
0.15.1 (UNRELEASED)
-------------------
- SECURITY FIX: 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)

0.15 (2015-05-08)
-------------------
- NetworkManager template: Restore nm-specific PropertiesChanged signal
Expand Down
13 changes: 5 additions & 8 deletions dbusmock/mockobject.py
Expand Up @@ -17,6 +17,7 @@
import sys
import types
import importlib
import imp
from xml.etree import ElementTree

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

def load_module(name):
if os.path.exists(name) and os.path.splitext(name)[1] == '.py':
sys.path.insert(0, os.path.dirname(os.path.abspath(name)))
try:
m = os.path.splitext(os.path.basename(name))[0]
module = importlib.import_module(m)
finally:
sys.path.pop(0)

return module
mod = imp.new_module(os.path.splitext(os.path.basename(name))[0])
with open(name) as f:
exec(f.read(), mod.__dict__, mod.__dict__)
return mod

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

Expand Down
10 changes: 10 additions & 0 deletions tests/test_api.py
Expand Up @@ -592,6 +592,16 @@ def load(mock, parameters):
self.addCleanup(p_mock.terminate)
self.addCleanup(p_mock.stdout.close)

# ensure that we don't use/write any .pyc files, they are dangerous
# in a world-writable directory like /tmp
self.assertFalse(os.path.exists(my_template.name + 'c'))
try:
from importlib.util import cache_from_source
self.assertFalse(os.path.exists(cache_from_source(my_template.name)))
except ImportError:
# python < 3.4
pass

self.assertEqual(dbus_ultimate.Answer(), 42)

# should appear in introspection
Expand Down

0 comments on commit 4e7d0df

Please sign in to comment.