Hello, see the attached file for r26 and r27 review notes.
@John: I'm still waiting for your answer about # ix implies m, so we don't need to add m if ix is present I have some profiles that contain "mrix" (for example sbin.dhclient and usr.sbin.ntpd), so either the old logprof was buggy or the comment is wrong ;-) Regards, Christian Boltz -- [Grundrechte] Natürlich gibt's da auch das berühme Recht auf freie Entfaltung. Andererseits: setzt das nicht auch zwingend vorraus, daß man vorher auch gehörig zusammengefaltet wurde? ;-) [Gerard Jensen in suse-linux]
=== modified file 'apparmor/aa.py' --- apparmor/aa.py 2013-07-24 16:42:34 +0000 +++ apparmor/aa.py 2013-07-27 10:02:12 +0000 - elif 'python' in interpreter: + elif interpreter == 'python': local_profile[localfile]['include']['abstractions/python'] = True ### 'python3' should also be allowed +def ask_the_question(): [...] + elif ans == 'CMD_DENY': + aa[profile][hat]['deny']['capability'][capability]['set'] = True + changed[profile] = True ### sidenote: an additional "ignore" option would be nice to just ignore a log event ### without adding anything to the profile. ### (usecase: starting sshd the very first time will write /etc/ssh/ssh_host_key, but you probably don't want ### to have write permissions for it in the profile) (distro-shipped profile may be an exception of course) + # If we get an mmap request, check if we already have it in allow_mode + if mode & AA_EXEC_MMAP: + # ix implies m, so we don't need to add m if ix is present ### hmm, some of my profiles disagree and have mrix... ### (John, any comments on this?) + + if not mode_contains(allow_mode, mode): + default_option = 1 + options = [] + newincludes = [] + include_valid = False + + for incname in include.keys(): + include_valid = False + # If already present skip + if aa[profile][hat][incname]: + continue + + if cfg['settings']['custom_includes']: + for incn in cfg['settings']['custom_includes'].split(): + if incn in incname: + include_valid = True + + if 'abstraction' in incname: + include_valid = True ### so I can add abstractions/doesnotexist and foobar/abstraction? ;-) ### (same for custom_includes) ### hints: ### - check if the file exists ### - use startswith 'abstractions/' instead of "in" + if not include_valid: + continue ### does this mean it's impossible to add an #include for files not in abstractions/ or custom_includes? ### I'd prefer not to forbid that ### (of course, check if the file exists etc.) + elif ans == 'CMD_ALLOW': + path = options[selected] + done = True + match = re.search('^#include\s+<(.+)>$', path) ### wrong regex: ### - space after #include is optional ### - fails with inline comments ### - if path is not trimmed, it fails with leading space ### (hint: a function "re_match_include(path) would be a good idea, you already have the correct regex somewhere else) + elif ans == 'CMD_GLOB': + newpath = options[selected].strip() + if not newpath.startswith('#include'): + if newpath[-1] == '/': + if newpath[-4:] == '/**/' or newpath[-3:] == '/*/': + # collapse one level to /**/ + newpath = re.sub('/[^/]+/\*{1,2}$/', '/\*\*/', newpath) + else: + newpath = re.sub('/[^/]+/$', '/\*/', newpath) ### what happens with /foo/bar**/ ? ### (should glob to /foo/**/ - but the code looks like it will be globbed to /foo/*/ ) + else: + if newpath[-3:] == '/**' or newpath[-2:] == '/*': + newpath = re.sub('/[^/]+/\*{1,2}$', '/\*\*', newpath) + elif re.search('/\*\*[^/]+$', newpath): + newpath = re.sub('/\*\*[^/]+$', '/\*\*', newpath) + else: + newpath = re.sub('/[^/]+$', '/\*', newpath) ### what happens with /foo/bar** ? ### (should be globbed to /foo/**, but the regex in elif doesn't cover it, so it becomes /foo/* in the else) + elif ans == 'CMD_GLOBEXT': + newpath = options[selected].strip() + if not newpath.startswith('#include'): + match = re.search('/\*{1,2}(\.[^/]+)$', newpath) ### some comments would make reading the regex easier ;-) ### /*.ext or /**.ext + if match: + newpath = re.sub('/[^/]+/\*{1,2}\.[^/]+$', '/\*\*'+match.group()[0], newpath) ### replace /foo/*.ext or /foo/**.ext with /**.ext + else: + match = re.search('(\.[^/]+)$') ### .ext + newpath = re.sub('/[^/]+(\.[^/]+)$', '/\*'+match.groups()[0], newpath) ### replace /foo.ext with /*.ext ### correct so far, but I have a corner case ;-) ### what happens with /foo/bar**.ext ? ### (probably becomes /foo/*.ext, which looks wrong) + for family in sorted(log_dict[aamode][profile][hat]['netdomain'].keys()): + # severity handling for net toggles goes here + for sock_type in sorted(log_dict[aaprofile][profile][hat]['netdomain'][family].keys()): + if profile_known_network(aa[profile][hat], family, sock_type): + continue + default_option = 1 + options = [] + newincludes = matchnetincludes(aa[profile][hat], family, sock_type) + q = hasher() + if newincludes: + options += map(lambda s: '#include <%s>'%s, sorted(set(newincludes))) + if options: + options.append('network %s %s' % (family, sock_type)) + q['options'] = options + q['selected'] = default_option - 1 + + q['headers'] = [gettext('Profile'), combine_name(profile, hat)] + q['headers'] += [gettext('Network Family'), family] + q['headers'] += [gettext('Socket Type'), sock_type] + + audit_toggle = 0 + q['functions'] = ['CMD_ALLOW', 'CMD_DENY', 'CMD_AUDIT_NEW', + 'CMD_ABORT', 'CMD_FINISHED'] + q['default'] = 'CMD_DENY' ### network rules should also allow globbing ### (not sure if "globbing" is the correct wording, but you should get the point) ### (most-permitting rule is just "network" without any additional parameters) + elif ans == 'CMD_ALLOW': + selection = options[selected] + done = True + if re.search('#include\s+<.+>$', selection): ### another wrong regex for #include + inc = re.search('#include\s+<(.+)>$', selection).groups()[0] ### and another one... ### (did I mention you should make this a function?)
-- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor