From 291dbefd074378df6b541fc1c19d3504279e069b Mon Sep 17 00:00:00 2001 From: Hector Cao Date: Wed, 20 Aug 2025 17:49:59 +0200 Subject: [PATCH] virt-aa-helper: Avoid duplicate when append rule when a device is dynamically attached to a VM, and it needs a special system access for apparmor, libvirt calls virt-aa-helper (with argument -F) to append a new rule to the apparmor profile of the VM. virt-aa-helper does not check for duplicate and blindly appends the rule to the profile. since there is no rule removal when a device is detached, this can make the profile grow in size if a big number of attach/detach operations are done and the profile might hit the size limit and futur attach operations might dysfunction because no rule can be added into the apparmor profile. this patch tries to mitigate this issue by doing a duplicate check when rules are appended into the profile. this fix does not guarantee the absence of duplicates but should be enough to prevent the profile to grow significantly in size and reach its size limit. Signed-off-by: Hector CAO Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/security/virt-aa-helper.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index b662d971cb..8a297d4b54 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -208,10 +208,21 @@ update_include_file(const char *include_file, const char *included_files, return -1; } - if (append && virFileExists(include_file)) + if (append && existing) { + /* Duplicate check: include_files might contain multiple rules + * the best is to check for each rule (separated by \n) but + * it might be overkilled, just do the check for the whole + * include_files. + * Most of the time, include_files contains only one rule + * so this check is OK to avoid the overflow of the profile + * duplicates might still exist though. + */ + if (strstr(existing, included_files) != NULL) + return 0; pcontent = g_strdup_printf("%s%s", existing, included_files); - else + } else { pcontent = g_strdup_printf("%s%s", warning, included_files); + } plen = strlen(pcontent); if (plen > MAX_FILE_LEN) { -- 2.47.2