From ff392e6f49383fc71f424cd41cd222bc2ebf6a3e Mon Sep 17 00:00:00 2001 From: John Johansen Date: Thu, 14 Jan 2021 10:46:50 -0800 Subject: [PATCH] parser: fix rule downgrade for unix rules Rule downgrades are used to provide some confinement when a feature is only partially supported by the kernel. Eg. On a kernel that doesn't support fine grained af_unix mediation but does support network mediation. unix (connect, receive, send) type=stream peer=(addr="@/tmp/.ICE-unix/[0-9]*"), will be downgraded to network unix type=stream, Which while more permissive still provides some mediation while allowing the appication to still function. However making the rule a deny rule result in tightening the profile. Eg. deny unix (connect, receive, send) type=stream peer=(addr="@/tmp/.ICE-unix/[0-9]*"), will be downgraded to deny network unix type=stream, and that deny rule will take priority over any allow rule. Which means that if the profile also had unix allow rules they will get blocked by the downgraded deny rule, because deny rules have a higher priority, and the application will break. Even worse there is no way to add the functionality back to the profile without deleting the offending deny rule. To fix this we drop deny rules that can't be downgraded in a way that won't break the application. Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1180766 MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/700 Signed-off-by: John Johansen (cherry picked from commit 855dbd4ac8ddb253343d6a81e094030c28233888) Signed-off-by: John Johansen --- parser/af_unix.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 98a9b657e..d1b1ea092 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -204,14 +204,18 @@ void unix_rule::downgrade_rule(Profile &prof) { yyerror(_("Memory allocation error.")); if (sock_type_n != -1) mask = 1 << sock_type_n; - if (deny) { - prof.net.deny[AF_UNIX] |= mask; - if (!audit) - prof.net.quiet[AF_UNIX] |= mask; - } else { + if (!deny) { prof.net.allow[AF_UNIX] |= mask; if (audit) prof.net.audit[AF_UNIX] |= mask; + } else { + /* deny rules have to be dropped because the downgrade makes + * the rule less specific meaning it will make the profile more + * restrictive and may end up denying accesses that might be + * allowed by the profile. + */ + if (warnflags & WARN_RULE_NOT_ENFORCED) + rule_t::warn_once(prof.name, "deny unix socket rule not enforced, can't be downgraded to generic network rule\n"); } }