summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-06-12 22:00:04 +0000
committerGerrit Code Review <review@openstack.org>2013-06-12 22:00:04 +0000
commitfb13686a00e933c17bca163b51fb3d7119d34e5a (patch)
tree35abd4ff5686b515ddb7753536e2571f2c286f1f
parentf9cc093ab6c3f34bd2f3bceb831ba6b937704a54 (diff)
parent8b95b1e91d46f1bc7a37d210dc15e6f4072afaaa (diff)
downloadoslo-fb13686a00e933c17bca163b51fb3d7119d34e5a.tar.gz
oslo-fb13686a00e933c17bca163b51fb3d7119d34e5a.tar.xz
oslo-fb13686a00e933c17bca163b51fb3d7119d34e5a.zip
Merge "Handle relative path arguments in Killfilter"
-rw-r--r--openstack/common/rootwrap/filters.py35
-rw-r--r--tests/unit/test_rootwrap.py14
2 files changed, 36 insertions, 13 deletions
diff --git a/openstack/common/rootwrap/filters.py b/openstack/common/rootwrap/filters.py
index ae7c62c..0cc55ce 100644
--- a/openstack/common/rootwrap/filters.py
+++ b/openstack/common/rootwrap/filters.py
@@ -34,7 +34,7 @@ class CommandFilter(object):
if self.real_exec is not None:
return self.real_exec
self.real_exec = ""
- if self.exec_path.startswith('/'):
+ if os.path.isabs(self.exec_path):
if os.access(self.exec_path, os.X_OK):
self.real_exec = self.exec_path
else:
@@ -164,8 +164,10 @@ class DeprecatedDnsmasqFilter(DnsmasqFilter):
class KillFilter(CommandFilter):
"""Specific filter for the kill calls.
+
1st argument is the user to run /bin/kill under
2nd argument is the location of the affected executable
+ if the argument is not absolute, it is checked against $PATH
Subsequent arguments list the accepted signals (if any)
This filter relies on /proc to accurately determine affected
@@ -194,21 +196,28 @@ class KillFilter(CommandFilter):
return False
try:
command = os.readlink("/proc/%d/exe" % int(args[1]))
- # NOTE(yufang521247): /proc/PID/exe may have '\0' on the
- # end, because python doen't stop at '\0' when read the
- # target path.
- command = command.split('\0')[0]
- # NOTE(dprince): /proc/PID/exe may have ' (deleted)' on
- # the end if an executable is updated or deleted
- if command.endswith(" (deleted)"):
- command = command[:command.rindex(" ")]
- if command != self.args[0]:
- # Affected executable does not match
- return False
except (ValueError, OSError):
# Incorrect PID
return False
- return True
+
+ # NOTE(yufang521247): /proc/PID/exe may have '\0' on the
+ # end, because python doen't stop at '\0' when read the
+ # target path.
+ command = command.partition('\0')[0]
+
+ # NOTE(dprince): /proc/PID/exe may have ' (deleted)' on
+ # the end if an executable is updated or deleted
+ if command.endswith(" (deleted)"):
+ command = command[:-len(" (deleted)")]
+
+ kill_command = self.args[0]
+
+ if os.path.isabs(kill_command):
+ return kill_command == command
+
+ return (os.path.isabs(command) and
+ kill_command == os.path.basename(command) and
+ os.path.dirname(command) in os.environ['PATH'].split(':'))
class ReadFileFilter(CommandFilter):
diff --git a/tests/unit/test_rootwrap.py b/tests/unit/test_rootwrap.py
index 25b2051..0e08b5e 100644
--- a/tests/unit/test_rootwrap.py
+++ b/tests/unit/test_rootwrap.py
@@ -107,6 +107,20 @@ class RootwrapTestCase(utils.BaseTestCase):
usercmd = ['kill', p.pid]
# Providing no signal should work
self.assertTrue(f.match(usercmd) or f2.match(usercmd))
+
+ # verify that relative paths are matched against $PATH
+ f = filters.KillFilter("root", "cat")
+ # Our own PID does not match so it should fail
+ usercmd = ['kill', os.getpid()]
+ self.assertFalse(f.match(usercmd))
+ # Filter should find cat in /bin or /usr/bin
+ usercmd = ['kill', p.pid]
+ self.assertTrue(f.match(usercmd))
+ # Filter shouldn't be able to find binary in $PATH, so fail
+ with fixtures.EnvironmentVariable("PATH", "/foo:/bar"):
+ self.assertFalse(f.match(usercmd))
+ pass
+
finally:
# Terminate the "cat" process and wait for it to finish
p.terminate()