Fixed the netrule persistence issue in cleanprof, some elementary work for mergeprof

This commit is contained in:
Kshitij Gupta 2013-09-23 02:14:11 +05:30
parent 93d59eb6eb
commit 0b0aeeda29
3 changed files with 56 additions and 40 deletions

View file

@ -7,7 +7,6 @@ import apparmor.aa as apparmor
import apparmor.cleanprofile as cleanprofile
parser = argparse.ArgumentParser(description=_('Perform a 3way merge on the given profiles'))
##parser.add_argument('profiles', type=str, nargs=3, help='MINE BASE OTHER')
parser.add_argument('mine', type=str, help=_('your profile'))
parser.add_argument('base', type=str, help=_('base profile'))
parser.add_argument('other', type=str, help=_('other profile'))
@ -17,13 +16,12 @@ args = parser.parse_args()
profiles = [args.mine, args.base, args.other]
if __name__ == '__main__':
main()
print(profiles)
def main():
mergeprofiles = Merge(profiles)
#Get rid of common/superfluous stuff
mergeprofiles.clear_common()
class Merge(object):
def __init__(self, profiles):
@ -31,45 +29,47 @@ class Merge(object):
#Read and parse base profile and save profile data, include data from it and reset them
apparmor.read_profile(base, True)
base = cleanprof.Prof()
#self.base_aa = apparmor.aa
#self.base_filelist = apparmor.filelist
#self.base_include = apparmor.include
reset()
base = cleanprofile.Prof(base)
self.reset()
#Read and parse other profile and save profile data, include data from it and reset them
apparmor.read_profile(other, True)
other = cleanprof.prof()
#self.other_aa = apparmor.aa
#self.other_filelist = apparmor.filelist
#self.other_include = apparmor.include
reset()
other = cleanprofile.Prof(other)
self.reset()
#Read and parse user profile
apparmor.read_profile(profiles[0], True)
user = cleanprof.prof()
#user_aa = apparmor.aa
#user_filelist = apparmor.filelist
#user_include = apparmor.include
user = cleanprofile.Prof(user)
def reset():
def reset(self):
apparmor.aa = apparmor.hasher()
apparmor.filelist = hasher()
apparmor.filelist = apparmor.hasher()
apparmor.include = dict()
apparmor.existing_profiles = hasher()
apparmor.original_aa = hasher()
apparmor.existing_profiles = apparmor.hasher()
apparmor.original_aa = apparmor.hasher()
def clear_common(self):
common_base_other()
remove_common('base')
remove_common('other')
deleted = 0
#Remove off the parts in other profile which are common/superfluous from user profile
user_other = cleanprofile.CleanProf(False, user, other)
deleted += user_other.compare_profiles()
#Remove off the parts in base profile which are common/superfluous from user profile
user_base = cleanprofile.CleanProf(False, user, base)
deleted += user_base.compare_profiles()
#Remove off the parts in other profile which are common/superfluous from base profile
base_other = cleanprofile.CleanProf(False, base, other)
deleted += user_base.compare_profiles()
def common_base_other(self):
def ask_the_questions(self):
pass
def remove_common(self, profile):
if prof1 == 'base':
if __name__ == '__main__':
main()
# def intersect(ra, rb):
# """Given two ranges return the range where they intersect or None.

View file

@ -2018,12 +2018,13 @@ def glob_path_withext(newpath):
def delete_net_duplicates(netrules, incnetrules):
deleted = 0
copy_netrules = deepcopy(netrules)
if incnetrules and netrules:
incnetglob = False
# Delete matching rules from abstractions
if incnetrules.get('all', False):
incnetglob = True
for fam in netrules.keys():
for fam in copy_netrules['rule'].keys():
if incnetglob or (type(incnetrules['rule'][fam]) != dict and incnetrules['rule'][fam]):
if type(netrules['rule'][fam]) == dict:
deleted += len(netrules['rule'][fam].keys())
@ -2035,7 +2036,7 @@ def delete_net_duplicates(netrules, incnetrules):
else:
for socket_type in netrules['rule'][fam].keys():
if incnetrules['rule'].get(fam, False):
netrules[fam].pop(socket_type)
netrules['rule'][fam].pop(socket_type)
deleted += 1
return deleted

View file

@ -15,17 +15,21 @@ class CleanProf:
#If same_file we're basically comparing the file against itself to check superfluous rules
self.same_file = same_file
self.profile = profile
self.other = profile
self.other = other
def compare_profiles(self):
deleted = 0
other_file_includes = list(self.other.filelist[self.profile.filename]['include'].keys())
#Remove the duplicate file-level includes from other
other_file_includes = list(self.other.profile.filename['include'].keys())
for rule in self.profile.filelist[self.profile.filename]:
for rule in self.profile.filelist[self.profile.filename]['include'].keys():
if rule in other_file_includes:
self.other.other.filename['include'].pop(rule)
self.other.filelist['include'].pop(rule)
for profile in self.profile.aa.keys():
self.remove_duplicate_rules(profile)
deleted += self.remove_duplicate_rules(profile)
return deleted
def remove_duplicate_rules(self, program):
#Process the profile of the program
@ -36,6 +40,12 @@ class CleanProf:
#The combined list of includes from profile and the file
includes = list(self.profile.aa[program][hat]['include'].keys()) + file_includes
#If different files remove duplicate includes in the other profile
if not self.same_file:
for inc in includes:
if self.other.aa[program][hat]['include'].get(inc, False):
self.other.aa[program][hat]['include'].pop(inc)
deleted += 1
#Clean up superfluous rules from includes in the other profile
for inc in includes:
if not self.profile.include.get(inc, {}).get(inc,False):
@ -62,8 +72,13 @@ class CleanProf:
for rule in profile[allow]['path'].keys():
for entry in profile_other[allow]['path'].keys():
if rule == entry:
if not same_profile:
deleted.append(entry)
#Check the modes
cm = profile[allow]['path'][rule]['mode']
am = profile[allow]['path'][rule]['audit']
#If modes of rule are a superset of rules implied by entry we can safely remove it
if apparmor.aa.mode_contains(cm, profile_other[allow]['path'][entry]['mode']) and apparmor.aa.mode_contains(am, profile_other[allow]['path'][entry]['audit']):
if not same_profile:
deleted.append(entry)
continue
if re.search('#?\s*include', rule) or re.search('#?\s*include', entry):
continue
@ -101,11 +116,11 @@ class CleanProf:
if netrules.get('all', False):
netglob = True
#Iterate over a copy of the rules in the other profile
for fam in copy_netrules_other.keys():
for fam in copy_netrules_other['rule'].keys():
if netglob or (type(netrules['rule'][fam]) != dict and netrules['rule'][fam]):
if not same_profile:
if type(netrules_other['rule'][fam] == dict):
deleted += len(netrules['rule'][fam].keys())
if type(netrules_other['rule'][fam]) == dict:
deleted += len(netrules_other['rule'][fam].keys())
else:
deleted += 1
netrules_other['rule'].pop(fam)