mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-02 15:25:27 +00:00
Merge hat parsing into ProfileStorage.parse()
... and into parse_profile_start_line() (which is used by ProfileStorage.parse()). With this change, the section handling RE_PROFILE_HAT_DEF in parse_profile_data() becomes superfluous. A nice side effect is that two simple_tests parse failures get accidently ;-) fixed.
This commit is contained in:
@@ -44,7 +44,7 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END,
|
|||||||
RE_PROFILE_HAT_DEF, RE_PROFILE_MOUNT,
|
RE_PROFILE_HAT_DEF, RE_PROFILE_MOUNT,
|
||||||
RE_PROFILE_PIVOT_ROOT,
|
RE_PROFILE_PIVOT_ROOT,
|
||||||
RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT,
|
RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT,
|
||||||
strip_quotes, parse_profile_start_line, re_match_include )
|
parse_profile_start_line, re_match_include )
|
||||||
|
|
||||||
from apparmor.profile_list import ProfileList, preamble_ruletypes
|
from apparmor.profile_list import ProfileList, preamble_ruletypes
|
||||||
|
|
||||||
@@ -1813,7 +1813,7 @@ def parse_profile_data(data, file, do_include, in_preamble):
|
|||||||
else:
|
else:
|
||||||
load_include(incname, in_preamble)
|
load_include(incname, in_preamble)
|
||||||
|
|
||||||
elif RE_PROFILE_START.search(line): # Starting line of a profile
|
elif RE_PROFILE_START.search(line) or RE_PROFILE_HAT_DEF.search(line): # Starting line of a 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,
|
# 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 "}".
|
# 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).
|
# The logic is simple and resembles a "poor man's stack" (with limited/hardcoded height).
|
||||||
@@ -1946,36 +1946,6 @@ def parse_profile_data(data, file, do_include, in_preamble):
|
|||||||
aaui.UI_Important(_('Ignoring no longer supported change hat declaration "^%(hat)s," found in file: %(file)s line: %(line)s') % {
|
aaui.UI_Important(_('Ignoring no longer supported change hat declaration "^%(hat)s," found in file: %(file)s line: %(line)s') % {
|
||||||
'hat': matches[0], 'file': file, 'line': lineno + 1 })
|
'hat': matches[0], 'file': file, 'line': lineno + 1 })
|
||||||
|
|
||||||
elif RE_PROFILE_HAT_DEF.search(line):
|
|
||||||
# An embedded hat syntax definition starts
|
|
||||||
matches = RE_PROFILE_HAT_DEF.search(line)
|
|
||||||
if not profile:
|
|
||||||
raise AppArmorException(_('Syntax Error: Unexpected hat definition found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 })
|
|
||||||
|
|
||||||
in_contained_hat = True
|
|
||||||
hat = matches.group('hat')
|
|
||||||
hat = strip_quotes(hat)
|
|
||||||
profname = combine_profname([profile, hat])
|
|
||||||
|
|
||||||
if profile_data.get(profname, False) and not do_include:
|
|
||||||
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) })
|
|
||||||
|
|
||||||
# if hat is already known, the check above will error out (if not do_include)
|
|
||||||
# nevertheless, just to be sure, don't overwrite existing profile_data.
|
|
||||||
if not profile_data.get(profname, False):
|
|
||||||
profile_data[profname] = ProfileStorage(profile, hat, 'parse_profile_data() hat_def')
|
|
||||||
profile_data[profname]['filename'] = file
|
|
||||||
profile_data[profname]['is_hat'] = True
|
|
||||||
|
|
||||||
flags = matches.group('flags')
|
|
||||||
|
|
||||||
profile_data[profname]['flags'] = flags
|
|
||||||
|
|
||||||
if initial_comment:
|
|
||||||
profile_data[profname]['initial_comment'] = initial_comment
|
|
||||||
initial_comment = ''
|
|
||||||
|
|
||||||
elif line[0] == '#':
|
elif line[0] == '#':
|
||||||
# Handle initial comments
|
# Handle initial comments
|
||||||
if not profile:
|
if not profile:
|
||||||
|
@@ -234,8 +234,11 @@ class ProfileStorage:
|
|||||||
prof_storage['name'] = profile
|
prof_storage['name'] = profile
|
||||||
prof_storage['filename'] = file
|
prof_storage['filename'] = file
|
||||||
prof_storage['external'] = pps_set_hat_external
|
prof_storage['external'] = pps_set_hat_external
|
||||||
prof_storage['attachment'] = matches['attachment'] or ''
|
|
||||||
prof_storage['flags'] = matches['flags']
|
prof_storage['flags'] = matches['flags']
|
||||||
|
prof_storage['is_hat'] = matches['is_hat']
|
||||||
|
|
||||||
|
if not matches['is_hat']:
|
||||||
|
prof_storage['attachment'] = matches['attachment'] or ''
|
||||||
prof_storage['xattrs'] = matches['xattrs']
|
prof_storage['xattrs'] = matches['xattrs']
|
||||||
|
|
||||||
return (profile, hat, prof_storage)
|
return (profile, hat, prof_storage)
|
||||||
|
@@ -112,19 +112,26 @@ RE_PROFILE_FILE_ENTRY = re.compile(
|
|||||||
|
|
||||||
|
|
||||||
def parse_profile_start_line(line, filename):
|
def parse_profile_start_line(line, filename):
|
||||||
|
common_sections = [ 'leadingspace', 'flags', 'comment']
|
||||||
|
|
||||||
|
sections = [ 'plainprofile', 'namedprofile', 'attachment', 'xattrs'] + common_sections
|
||||||
matches = RE_PROFILE_START.search(line)
|
matches = RE_PROFILE_START.search(line)
|
||||||
|
|
||||||
|
if not matches:
|
||||||
|
sections = ['hat_keyword', 'hat'] + common_sections
|
||||||
|
matches = RE_PROFILE_HAT_DEF.search(line)
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
raise AppArmorBug('The given line from file %(filename)s is not the start of a profile: %(line)s' % { 'filename': filename, 'line': line } )
|
raise AppArmorBug('The given line from file %(filename)s is not the start of a profile: %(line)s' % { 'filename': filename, 'line': line } )
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for section in [ 'leadingspace', 'plainprofile', 'namedprofile', 'attachment', 'xattrs', 'flags', 'comment']:
|
for section in sections:
|
||||||
if matches.group(section):
|
if matches.group(section):
|
||||||
result[section] = matches.group(section)
|
result[section] = matches.group(section)
|
||||||
|
|
||||||
# sections with optional quotes
|
# sections with optional quotes
|
||||||
if section in ['plainprofile', 'namedprofile', 'attachment']:
|
if section in ['plainprofile', 'namedprofile', 'attachment', 'hat']:
|
||||||
result[section] = strip_quotes(result[section])
|
result[section] = strip_quotes(result[section])
|
||||||
else:
|
else:
|
||||||
result[section] = None
|
result[section] = None
|
||||||
@@ -132,7 +139,12 @@ def parse_profile_start_line(line, filename):
|
|||||||
if result['flags'] and result['flags'].strip() == '':
|
if result['flags'] and result['flags'].strip() == '':
|
||||||
raise AppArmorException(_('Invalid syntax in %(filename)s: Empty set of flags in line %(line)s.' % { 'filename': filename, 'line': line } ))
|
raise AppArmorException(_('Invalid syntax in %(filename)s: Empty set of flags in line %(line)s.' % { 'filename': filename, 'line': line } ))
|
||||||
|
|
||||||
if result['plainprofile']:
|
result['is_hat'] = False
|
||||||
|
if result.get('hat'):
|
||||||
|
result['is_hat'] = True
|
||||||
|
result['profile'] = result['hat']
|
||||||
|
result['profile_keyword'] = True
|
||||||
|
elif result['plainprofile']:
|
||||||
result['profile'] = result['plainprofile']
|
result['profile'] = result['plainprofile']
|
||||||
result['profile_keyword'] = False
|
result['profile_keyword'] = False
|
||||||
else:
|
else:
|
||||||
|
@@ -141,7 +141,6 @@ exception_not_raised = [
|
|||||||
'profile/flags/flags_bad44.sd',
|
'profile/flags/flags_bad44.sd',
|
||||||
'profile/flags/flags_bad45.sd',
|
'profile/flags/flags_bad45.sd',
|
||||||
'profile/flags/flags_bad46.sd',
|
'profile/flags/flags_bad46.sd',
|
||||||
'profile/simple_bad_no_close_brace4.sd',
|
|
||||||
'profile/profile_ns_bad8.sd', # 'profile :ns/t' without terminating ':'
|
'profile/profile_ns_bad8.sd', # 'profile :ns/t' without terminating ':'
|
||||||
'ptrace/bad_05.sd', # actually contains a capability rule with invalid (ptrace-related) keyword
|
'ptrace/bad_05.sd', # actually contains a capability rule with invalid (ptrace-related) keyword
|
||||||
'ptrace/bad_06.sd', # actually contains a capability rule with invalid (ptrace-related) keyword
|
'ptrace/bad_06.sd', # actually contains a capability rule with invalid (ptrace-related) keyword
|
||||||
@@ -306,9 +305,6 @@ syntax_failure = [
|
|||||||
# missing profile keywords
|
# missing profile keywords
|
||||||
'profile/re_named_ok2.sd',
|
'profile/re_named_ok2.sd',
|
||||||
|
|
||||||
# Syntax Error: Unexpected hat definition found (external hat)
|
|
||||||
'change_hat/new_style4.sd',
|
|
||||||
|
|
||||||
# Syntax Errors caused by boolean conditions (parse_profile_data() gets confused by the closing '}')
|
# Syntax Errors caused by boolean conditions (parse_profile_data() gets confused by the closing '}')
|
||||||
'conditional/defined_1.sd',
|
'conditional/defined_1.sd',
|
||||||
'conditional/defined_2.sd',
|
'conditional/defined_2.sd',
|
||||||
|
Reference in New Issue
Block a user