mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
Fixed the netrule persistence issue in cleanprof, some elementary work for mergeprof
This commit is contained in:
parent
93d59eb6eb
commit
0b0aeeda29
3 changed files with 56 additions and 40 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue