2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 05:47:59 +00:00

Use PivotRootRule and PivotRootRuleset

... for handling pivot_root rules.

This replaces the old code that just stores the full rule as text.

We also get rid of the old ['allow'] and ['deny'] items in
ProfileStorage, the handling of old write functions, and the last usage
of _Raw_Rule (and therefore _Raw_Rule itsself).

Also delete the old test-pivot_root_parse.py which relied on the ancient
code, and even used a wrong syntax in its test rules.
This commit is contained in:
Christian Boltz 2024-05-10 22:11:28 +02:00
parent c48f7b625a
commit a15a33474d
No known key found for this signature in database
GPG Key ID: C6A682EA63C82F1C
7 changed files with 8 additions and 139 deletions

View File

@ -26,7 +26,6 @@ from tempfile import NamedTemporaryFile
import apparmor.config
import apparmor.logparser
import apparmor.rules as aarules
import apparmor.severity
import apparmor.ui as aaui
from apparmor.aare import AARE
@ -38,7 +37,7 @@ from apparmor.profile_storage import ProfileStorage, add_or_remove_flag, ruletyp
from apparmor.regex import (
RE_HAS_COMMENT_SPLIT, RE_PROFILE_CHANGE_HAT, RE_PROFILE_CONDITIONAL,
RE_PROFILE_CONDITIONAL_BOOLEAN, RE_PROFILE_CONDITIONAL_VARIABLE, RE_PROFILE_END,
RE_PROFILE_HAT_DEF, RE_PROFILE_PIVOT_ROOT, RE_PROFILE_START,
RE_PROFILE_HAT_DEF, RE_PROFILE_START,
RE_RULE_HAS_COMMA, parse_profile_start_line, re_match_include)
from apparmor.rule.abi import AbiRule
from apparmor.rule.capability import CapabilityRule
@ -1955,29 +1954,6 @@ def parse_profile_data(data, file, do_include, in_preamble):
# Conditional Boolean defined
pass
elif RE_PROFILE_PIVOT_ROOT.search(line):
matches = RE_PROFILE_PIVOT_ROOT.search(line).groups()
if not profile:
raise AppArmorException(_('Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: %(line)s')
% {'file': file, 'line': lineno + 1})
audit = False
if matches[0]:
audit = True
allow = 'allow'
if matches[1] and matches[1].strip() == 'deny':
allow = 'deny'
pivot_root = matches[2].strip()
pivot_root_rule = parse_pivot_root_rule(pivot_root)
pivot_root_rule.audit = audit
pivot_root_rule.deny = (allow == 'deny')
pivot_root_rules = profile_data[profname][allow].get('pivot_root', [])
pivot_root_rules.append(pivot_root_rule)
profile_data[profname][allow]['pivot_root'] = pivot_root_rules
elif RE_PROFILE_CHANGE_HAT.search(line):
matches = RE_PROFILE_CHANGE_HAT.search(line).groups()
@ -2065,6 +2041,7 @@ def match_line_against_rule_classes(line, profile, file, lineno, in_preamble):
'mqueue',
'io_uring',
'mount',
'pivot_root',
'unix',
):
@ -2117,11 +2094,6 @@ def split_to_merged(profile_data):
return merged
def parse_pivot_root_rule(line):
# XXX Do real parsing here
return aarules.Raw_Pivot_Root_Rule(line)
def write_piece(profile_data, depth, name, nhat):
pre = ' ' * depth
data = []

View File

@ -20,8 +20,6 @@ import termios
import tty
from tempfile import NamedTemporaryFile
import apparmor.rules as rules
DEBUGGING = False
@ -106,8 +104,6 @@ def recursive_print(src, dpth=0, key=''):
for litem in src:
recursive_print(litem, dpth + 1)
print(tabs + "]")
elif isinstance(src, rules._Raw_Rule):
src.recursive_print(dpth)
else:
if key:
print(tabs + '%s = %s' % (key, src))

View File

@ -32,6 +32,7 @@ from apparmor.rule.userns import UserNamespaceRule, UserNamespaceRuleset
from apparmor.rule.mqueue import MessageQueueRule, MessageQueueRuleset
from apparmor.rule.io_uring import IOUringRule, IOUringRuleset
from apparmor.rule.mount import MountRule, MountRuleset
from apparmor.rule.pivot_root import PivotRootRule, PivotRootRuleset
from apparmor.rule.unix import UnixRule, UnixRuleset
from apparmor.translations import init_translation
@ -54,8 +55,8 @@ ruletypes = {
'mqueue': {'rule': MessageQueueRule, 'ruleset': MessageQueueRuleset},
'io_uring': {'rule': IOUringRule, 'ruleset': IOUringRuleset},
'mount': {'rule': MountRule, 'ruleset': MountRuleset},
'pivot_root': {'rule': PivotRootRule, 'ruleset': PivotRootRuleset},
'unix': {'rule': UnixRule, 'ruleset': UnixRuleset},
}
@ -87,13 +88,6 @@ class ProfileStorage:
data['is_hat'] = False # profile or hat?
data['hat_keyword'] = False # True for 'hat foo', False for '^foo'
data['allow'] = dict()
data['deny'] = dict()
# pivot_root has a .get() fallback to list() - initialize it nevertheless
data['allow']['pivot_root'] = []
data['deny']['pivot_root'] = []
self.data = data
def __getitem__(self, key):
@ -184,11 +178,6 @@ class ProfileStorage:
Note that the profile header and the closing "}" are _not_ included.
"""
# "old" write functions for rule types not implemented as *Rule class yet
write_functions = {
'pivot_root': write_pivot_root,
}
write_order = [
'abi',
'inc_ie',
@ -211,9 +200,6 @@ class ProfileStorage:
data = []
for ruletype in write_order:
if write_functions.get(ruletype):
data.extend(write_functions[ruletype](self.data, depth))
else:
data.extend(self.data[ruletype].get_clean(depth))
return data
@ -310,23 +296,3 @@ def var_transform(ref):
value = '""'
data.append(quote_if_needed(value))
return ' '.join(data)
def write_pivot_root_rules(prof_data, depth, allow):
pre = ' ' * depth
data = []
# no pivot_root rules, so return
if not prof_data[allow].get('pivot_root', False):
return data
for pivot_root_rule in prof_data[allow]['pivot_root']:
data.append('%s%s' % (pre, pivot_root_rule.serialize()))
data.append('')
return data
def write_pivot_root(prof_data, depth):
data = write_pivot_root_rules(prof_data, depth, 'deny')
data.extend(write_pivot_root_rules(prof_data, depth, 'allow'))
return data

View File

@ -1,33 +0,0 @@
# ------------------------------------------------------------------
#
# Copyright (C) 2014 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# ------------------------------------------------------------------
class _Raw_Rule:
audit = False
deny = False
def __init__(self, rule):
self.rule = rule
def serialize(self):
return "%s%s%s" % ('audit ' if self.audit else '',
'deny ' if self.deny else '',
self.rule)
def recursive_print(self, depth):
tabs = ' ' * depth * 4
print('%s[%s]' % (tabs, type(self).__name__))
tabs += ' ' * 4
print('%saudit = %s' % (tabs, self.audit))
print('%sdeny = %s' % (tabs, self.deny))
print('%sraw rule = %s' % (tabs, self.rule))
class Raw_Pivot_Root_Rule(_Raw_Rule):
pass

View File

@ -21,7 +21,7 @@ COMMONDIR=../../common/
include $(COMMONDIR)/Make.rules
# files that don't have 100% test coverage
INCOMPLETE_COVERAGE=libraries/libapparmor/swig/python/.*/LibAppArmor/LibAppArmor.py|utils/aa-logprof|utils/apparmor/aa.py|utils/apparmor/common.py|utils/apparmor/config.py|utils/apparmor/easyprof.py|utils/apparmor/fail.py|utils/apparmor/logparser.py|utils/apparmor/profile_storage.py|utils/apparmor/rules.py|utils/apparmor/ui.py|minitools_test.py
INCOMPLETE_COVERAGE=libraries/libapparmor/swig/python/.*/LibAppArmor/LibAppArmor.py|utils/aa-logprof|utils/apparmor/aa.py|utils/apparmor/common.py|utils/apparmor/config.py|utils/apparmor/easyprof.py|utils/apparmor/fail.py|utils/apparmor/logparser.py|utils/apparmor/ui.py|minitools_test.py
ifdef USE_SYSTEM

View File

@ -1,33 +0,0 @@
#! /usr/bin/python3
# ------------------------------------------------------------------
#
# Copyright (C) 2014 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# ------------------------------------------------------------------
import unittest
import apparmor.aa as aa
from common_test import AAParseTest, setup_aa, setup_regex_tests
class AAParsePivotRootTest(AAParseTest):
def setUp(self):
self.parse_function = aa.parse_pivot_root_rule
tests = (
('pivot_root,', 'pivot_root base keyword'),
('pivot_root /old,', 'pivot_root oldroot rule'),
('pivot_root /old /new,', 'pivot_root old and new root rule'),
('pivot_root /old /new -> /usr/bin/child,', 'pivot_root child rule'),
)
setup_aa(aa)
if __name__ == '__main__':
setup_regex_tests(AAParsePivotRootTest)
unittest.main(verbosity=1)

View File

@ -16,6 +16,7 @@ from apparmor.common import AppArmorBug, AppArmorException
from apparmor.regex import (
RE_PROFILE_CAP, RE_PROFILE_DBUS, RE_PROFILE_MOUNT, RE_PROFILE_PTRACE, RE_PROFILE_SIGNAL,
RE_PROFILE_START, parse_profile_start_line, re_match_include, RE_PROFILE_UNIX,
RE_PROFILE_PIVOT_ROOT,
re_match_include_parse, strip_parenthesis, strip_quotes)
from common_test import AATest, setup_aa, setup_all_loops
@ -313,7 +314,7 @@ class AARegexPivotRoot(AARegexTest):
"""Tests for RE_PROFILE_PIVOT_ROOT"""
def AASetup(self):
self.regex = aa.RE_PROFILE_PIVOT_ROOT
self.regex = RE_PROFILE_PIVOT_ROOT
tests = (
(' pivot_root,', (None, None, 'pivot_root,', None, None)),