utils: fix file handling of old perms with owner

When the profile already contains a "file" rule containing the owner
prefix and the tool is trying to handle a new file entry, it tries to
show it in the logprof header as "old mode".

The issue is that when the owner rule is an implicit all files
permission, then the object "FileRule" is used instead of the set of
permissions. When subtracting FileRule from set() a TypeError
exception is thrown.

Fix this by "translating" FileRule.ALL perms to "mrwlkix".

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/429
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
Georgia Garcia 2024-09-03 12:10:39 -03:00
parent 729e28e8b2
commit 39f84c3767
2 changed files with 25 additions and 2 deletions

View file

@ -26,6 +26,7 @@ allow_exec_transitions = ('ix', 'ux', 'Ux', 'px', 'Px', 'cx', 'Cx') # 2 chars -
allow_exec_fallback_transitions = ('pix', 'Pix', 'cix', 'Cix', 'pux', 'PUx', 'cux', 'CUx') # 3 chars - len relevant for split_perms()
deny_exec_transitions = ('x')
file_permissions = ('m', 'r', 'w', 'a', 'l', 'k', 'link', 'subset') # also defines the write order
implicit_all_permissions = ('m', 'r', 'w', 'l', 'k')
class FileRule(BaseRule):
@ -356,9 +357,21 @@ class FileRule(BaseRule):
old_mode = ''
if self.original_perms:
original_perms_all = self._join_given_perms(self.original_perms['allow']['all'], None)
original_perms_set = {}
for who in ['all', 'owner']:
original_perms_set[who] = {}
original_perms_set[who]['perms'] = self.original_perms['allow'][who]
original_perms_set[who]['exec_perms'] = None
if self.original_perms['allow'][who] == FileRule.ALL:
original_perms_set[who]['perms'] = set(implicit_all_permissions)
original_perms_set[who]['exec_perms'] = 'ix'
original_perms_all = self._join_given_perms(original_perms_set['all']['perms'],
original_perms_set['all']['exec_perms'])
original_perms_owner = self._join_given_perms(
self.original_perms['allow']['owner'] - self.original_perms['allow']['all'], None) # only list owner perms that are not covered by other perms
original_perms_set['owner']['perms'] - original_perms_set['all']['perms'], # only list owner perms that are not covered by other perms
original_perms_set['owner']['exec_perms'])
if original_perms_all and original_perms_owner:
old_mode = '%s + owner %s' % (original_perms_all, original_perms_owner)

View file

@ -866,6 +866,16 @@ class FileLogprofHeaderTest(AATest):
obj.original_perms = {'allow': {'all': set(), 'owner': set()}}
self.assertEqual(obj.logprof_header(), [_('Path'), '/foo', _('New Mode'), _('rw')])
def test_implicit_original_perms(self):
obj = FileRule.create_instance('/foo rw,')
obj.original_perms = {'allow': {'all': FileRule.ALL, 'owner': set()}}
self.assertEqual(obj.logprof_header(), [_('Path'), '/foo', _('Old Mode'), _('mrwlkix'), _('New Mode'), _('rw')])
def test_owner_implicit_original_perms(self):
obj = FileRule.create_instance('/foo rw,')
obj.original_perms = {'allow': {'all': set(), 'owner': FileRule.ALL}}
self.assertEqual(obj.logprof_header(), [_('Path'), '/foo', _('Old Mode'), _('owner mrwlkix'), _('New Mode'), _('rw')])
class FileEditHeaderTest(AATest):
def _run_test(self, params, expected):