Merge branch 'cboltz-parse-profile-start' into 'master'

split off parse_profile_start_to_storage() from parse_profile_data()

See merge request apparmor/apparmor!710

Acked-by: Steve Beattie <steve.beattie@canonical.com>
This commit is contained in:
Christian Boltz 2021-02-25 11:20:52 +00:00
commit 0f21ca6173
2 changed files with 59 additions and 30 deletions

View file

@ -1788,7 +1788,6 @@ def parse_profile_start(line, file, lineno, profile, hat):
'profile': profile, 'file': file, 'line': lineno + 1 })
hat = matches['profile']
in_contained_hat = True
pps_set_profile = True
pps_set_hat_external = False
@ -1803,14 +1802,34 @@ def parse_profile_start(line, file, lineno, profile, hat):
hat = profile
pps_set_hat_external = False
in_contained_hat = False
pps_set_profile = False
attachment = matches['attachment']
flags = matches['flags']
xattrs = matches['xattrs']
return (profile, hat, attachment, xattrs, flags, in_contained_hat, pps_set_profile, pps_set_hat_external)
return (profile, hat, attachment, xattrs, flags, pps_set_profile, pps_set_hat_external)
def parse_profile_start_to_storage(line, file, lineno, profile, hat):
''' parse a profile start line (using parse_profile_startline()) and convert it to a ProfileStorage '''
(profile, hat, attachment, xattrs, flags, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat)
prof_storage = ProfileStorage(profile, hat, 'parse_profile_data() profile_start')
if attachment:
prof_storage['attachment'] = attachment
if pps_set_profile:
prof_storage['profile'] = True
if pps_set_hat_external:
prof_storage['external'] = True
prof_storage['name'] = profile
prof_storage['filename'] = file
prof_storage['xattrs'] = xattrs
prof_storage['flags'] = flags
return (profile, hat, prof_storage)
def parse_profile_data(data, file, do_include):
profile_data = hasher()
@ -1837,27 +1856,21 @@ def parse_profile_data(data, file, do_include):
lastline = None
# Starting line of a profile
if RE_PROFILE_START.search(line):
(profile, hat, attachment, xattrs, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat)
# in_contained_hat is needed to know if we are already in a profile or not. (Simply checking if we are in a hat doesn't work,
# because something like "profile foo//bar" will set profile and hat at once, and later (wrongfully) expect another "}".
# The logic is simple and resembles a "poor man's stack" (with limited/hardcoded height).
if profile:
in_contained_hat = True
else:
in_contained_hat = False
(profile, hat, prof_storage) = parse_profile_start_to_storage(line, file, lineno, profile, hat)
if profile_data[profile].get(hat, False):
raise AppArmorException('Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' %
{ 'file': file, 'line': lineno + 1, 'profile': combine_name(profile, hat) })
profile_data[profile][hat] = ProfileStorage(profile, hat, 'parse_profile_data() profile_start')
if attachment:
profile_data[profile][hat]['attachment'] = attachment
if pps_set_profile:
profile_data[profile][hat]['profile'] = True
if pps_set_hat_external:
profile_data[profile][hat]['external'] = True
# save profile name and filename
profile_data[profile][hat]['name'] = profile
profile_data[profile][hat]['filename'] = file
profile_data[profile][hat]['xattrs'] = xattrs
profile_data[profile][hat]['flags'] = flags
profile_data[profile][hat] = prof_storage
# Save the initial comment
if initial_comment:

View file

@ -20,7 +20,7 @@ import sys
import apparmor.aa # needed to set global vars in some tests
from apparmor.aa import (check_for_apparmor, get_output, get_reqs, get_interpreter_and_abstraction, create_new_profile,
get_profile_flags, change_profile_flags, set_options_audit_mode, set_options_owner_mode, is_skippable_file, is_skippable_dir,
parse_profile_start, parse_profile_data, write_header,
parse_profile_start, parse_profile_start_to_storage, parse_profile_data, write_header,
get_file_perms, propose_file_rules)
from apparmor.aare import AARE
from apparmor.common import AppArmorException, AppArmorBug
@ -507,16 +507,16 @@ class AaTest_is_skippable_dir(AATest):
class AaTest_parse_profile_start(AATest):
tests = [
# profile start line profile hat profile hat attachment xattrs flags in_contained_hat, pps_set_profile, pps_set_hat_external
(('/foo {', None, None), ('/foo', '/foo', None, None, None, False, False, False)),
(('/foo (complain) {', None, None), ('/foo', '/foo', None, None, 'complain', False, False, False)),
(('profile foo /foo {', None, None), ('foo', 'foo', '/foo', None, None, False, False, False)), # named profile
(('profile /foo {', '/bar', '/bar'), ('/bar', '/foo', None, None, None, True, True, False)), # child profile
(('/foo//bar {', None, None), ('/foo', 'bar', None, None, None, False, False, True )), # external hat
(('profile "/foo" (complain) {', None, None), ('/foo', '/foo', None, None, 'complain', False, False, False)),
(('profile "/foo" xattrs=(user.bar=bar) {', None, None), ('/foo', '/foo', None, 'user.bar=bar', None, False, False, False)),
(('profile "/foo" xattrs=(user.bar=bar user.foo=*) {', None, None), ('/foo', '/foo', None, 'user.bar=bar user.foo=*', None, False, False, False)),
(('/usr/bin/xattrs-test xattrs=(myvalue="foo.bar") {', None, None), ('/usr/bin/xattrs-test', '/usr/bin/xattrs-test', None, 'myvalue="foo.bar"', None, False, False, False)),
# profile start line profile hat profile hat attachment xattrs flags pps_set_profile, pps_set_hat_external
(('/foo {', None, None), ('/foo', '/foo', None, None, None, False, False)),
(('/foo (complain) {', None, None), ('/foo', '/foo', None, None, 'complain', False, False)),
(('profile foo /foo {', None, None), ('foo', 'foo', '/foo', None, None, False, False)), # named profile
(('profile /foo {', '/bar', '/bar'), ('/bar', '/foo', None, None, None, True, False)), # child profile
(('/foo//bar {', None, None), ('/foo', 'bar', None, None, None, False, True )), # external hat
(('profile "/foo" (complain) {', None, None), ('/foo', '/foo', None, None, 'complain', False, False)),
(('profile "/foo" xattrs=(user.bar=bar) {', None, None), ('/foo', '/foo', None, 'user.bar=bar', None, False, False)),
(('profile "/foo" xattrs=(user.bar=bar user.foo=*) {', None, None), ('/foo', '/foo', None, 'user.bar=bar user.foo=*', None, False, False)),
(('/usr/bin/xattrs-test xattrs=(myvalue="foo.bar") {', None, None), ('/usr/bin/xattrs-test', '/usr/bin/xattrs-test', None, 'myvalue="foo.bar"', None, False, False)),
]
def _run_test(self, params, expected):
@ -524,6 +524,19 @@ class AaTest_parse_profile_start(AATest):
self.assertEqual(parsed, expected)
(profile, hat, prof_storage) = parse_profile_start_to_storage(params[0], 'somefile', 1, params[1], params[2])
self.assertEqual(profile, expected[0])
self.assertEqual(hat, expected[1])
if expected[2] is None:
self.assertEqual(prof_storage['attachment'], '')
else:
self.assertEqual(prof_storage['attachment'], expected[2])
self.assertEqual(prof_storage['xattrs'], expected[3])
self.assertEqual(prof_storage['flags'], expected[4])
self.assertEqual(prof_storage['profile'], expected[5])
self.assertEqual(prof_storage['external'], expected[6])
class AaTest_parse_profile_start_errors(AATest):
tests = [
(('/foo///bar///baz {', None, None), AppArmorException), # XXX deeply nested external hat
@ -535,6 +548,9 @@ class AaTest_parse_profile_start_errors(AATest):
with self.assertRaises(expected):
parse_profile_start(params[0], 'somefile', 1, params[1], params[2])
with self.assertRaises(expected):
parse_profile_start_to_storage(params[0], 'somefile', 1, params[1], params[2])
class AaTest_parse_profile_data(AATest):
def test_parse_empty_profile_01(self):
prof = parse_profile_data('/foo {\n}\n'.split(), 'somefile', False)