blob: 3f3ab0f0dd33752c253ce86c04e149f4b9104fe8 [file] [log] [blame]
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
import os.path
class security_ReservedPrivileges(test.test):
version = 1
def reserved_commands(self, command_list):
process_list = []
for line in command_list:
items = line.split()
# Remove the zombie label
try:
items.remove('<defunct>')
except ValueError, e:
# The item wasn't in the list, that's ok
pass
# There are n items in the list. The first is the command, all of
# the remaining are either the different users or groups. They
# must all match, if they don't we collect it.
matches = [i for i,owners in enumerate(items) if owners == items[1]]
# We do < because some processes have the same name as their owner.
# in that case the number of items will equal the number of matches
if (len(matches) < (len(items) - 1)):
process_list.append(items[0])
return set(process_list)
def load_baseline(self, bltype):
# Figure out path to baseline file, by looking up our own path
path = os.path.abspath(__file__)
path = os.path.join(os.path.dirname(path), 'baseline.%s' % bltype)
if (os.path.isfile(path) == False):
return set([])
baseline_file = open(path)
baseline_data = baseline_file.read()
baseline_set = set(baseline_data.splitlines())
baseline_file.close()
return baseline_set
def run_once(self, owner_type='user'):
"""
Do a find on the system for commands with reserved privileges and
compare against baseline. Fail if these do not match.
"""
if (owner_type == 'user'):
command = ('ps --no-headers -eo comm,euser,ruser,suser,fuser')
else:
command = ('ps --no-headers -eo comm,rgroup,group')
command_output = utils.system_output(command, ignore_status=True)
observed_set = self.reserved_commands(command_output.splitlines())
baseline_set = self.load_baseline(owner_type)
# If something in the observed set is not
# covered by the baseline...
diff = observed_set.difference(baseline_set)
if len(diff) > 0:
for command in diff:
logging.error('Unexpected command: %s' % command)
# Or, things in baseline are missing from the system:
diff2 = baseline_set.difference(observed_set)
if len(diff2) > 0:
for command in diff2:
logging.error('Missing command: %s' % command)
if (len(diff) + len(diff2)) > 0:
raise error.TestFail('Baseline mismatch')