Merge aa-mergeprof: prevent backtrace if file not found

If a user specifies a non-existing file to merge into the profiles
(`aa-mergeprof /file/not/found`), this results in a backtrace showing an
AppArmorBug because that file unsurprisingly doesn't end up in the
active_profiles filelist.

Handle this more gracefully by adding a read_error_fatal parameter to
read_profile() that, if set, forwards the exception. With that,
aa-mergeprof doesn't try to list the profiles in this non-existing file.

Note that all other callers of read_profile() continue to ignore read
errors, because aborting just because a single file in /etc/apparmor.d/
(for example a broken symlink) isn't readable would be a bad idea.

This bug was introduced in 4e09f315c3, therefore I propose this patch for 3.0..master

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1403
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
(cherry picked from commit 5ebbe788ea)
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2024-11-06 03:11:27 +00:00 committed by John Johansen
parent be8d85603e
commit 5c04b791d2
2 changed files with 11 additions and 5 deletions

View file

@ -42,9 +42,12 @@ profiles = args.files
def find_profiles_from_files(files):
profile_to_filename = dict()
for file_name in files:
apparmor.aa.read_profile(file_name, True)
for profile_name in apparmor.aa.active_profiles.profiles_in_file(file_name):
profile_to_filename[profile_name] = file_name
try:
apparmor.aa.read_profile(file_name, True, read_error_fatal=True)
for profile_name in apparmor.aa.active_profiles.profiles_in_file(file_name):
profile_to_filename[profile_name] = file_name
except IOError:
pass
apparmor.aa.reset_aa()
return profile_to_filename

View file

@ -1677,7 +1677,7 @@ def read_inactive_profiles(skip_profiles=()):
read_profile(full_file, False)
def read_profile(file, active_profile):
def read_profile(file, active_profile, read_error_fatal=False):
data = None
try:
with open_file_read(file) as f_in:
@ -1685,7 +1685,10 @@ def read_profile(file, active_profile):
except IOError as e:
aaui.UI_Important('WARNING: Error reading file %s, skipping.\n %s' % (file, e))
debug_logger.debug("read_profile: can't read %s - skipping", file)
return
if read_error_fatal:
raise (e)
else:
return
profile_data = parse_profile_data(data, file, 0, True)