I prototyped a parser fix for the deny/cont-match poisoning from my
previous comment, on top of the v5.0.2 tag.
Root cause, confirmed with the parser's own DFA state dump (-D dfa-
states): when any "deny network ..." rule is present, the mandatory
AA_CONT_MATCH stub that gen_net_rule() emits at the family+type prefix
vanishes from the compiled DFA entirely (zero states carry 0x10000000,
versus five without the deny). Two places conspire:
1. gen_net_rule() emits the prefix stub with rule_mode_t::UNSPECIFIED, so a
deny rule emits the stub as a DENY rule; the structural cont-match bit lands in
the state's deny mask.
2. Both deny-merge paths then clear it from the allow set: pri_update_perm()'s
DENYMATCHFLAG branch (perms.allow &= ~amask, where the deny stub's amask
contains the cont-match bit) and perms_t::apply_and_clear_deny() (allow &=
~deny), which runs by default via CONTROL_DFA_FILTER_DENY.
Fix: treat the cont-match bit as structural, not grantable - a deny must
never clear it. Two small changes in parser/libapparmor_re:
- hfa.cc, pri_update_perm() DENYMATCHFLAG branch: after clearing, restore
perms.allow |= match->perms & amask & AA_COMPAT_CONT_MATCH;
- hfa.h, perms_t::apply_and_clear_deny(): after clearing, restore
allow |= deny & AA_COMPAT_CONT_MATCH;
Verification with the DFA-walking tool against the exact QRT profile
(with both deny connect rules):
create bind listen accept send connect
5.0.2 (unpatched) DENIED DENIED DENIED DENIED DENIED DENIED
5.0.2 + fix DENIED ALLOWED ALLOWED ALLOWED ALLOWED DENIED
(create remains DENIED because the profile does not grant it - the test-
profile fix from comment 3 is still needed; connect remains DENIED, as
the deny rule intends.)
Additional checks with the patched parser:
- Selective deny still works: "network (connect) ip=127.0.0.1 port=8080," +
"deny network (connect) ip=10.0.0.1," allows connect to 127.0.0.1 and denies
10.0.0.1.
- Broad grant + specific deny: "network inet stream," + "deny network (connect)
ip=10.0.0.1," allows create/bind/connect except connect to 10.0.0.1.
- Deny-only profile still denies.
- The deny poisoning is not address-scoped: before the fix, "deny network
(connect) ip=10.0.0.1," also broke "network (bind) ip=127.0.0.1 port=8080,".
After the fix, the bind rule works.
Parser test suite (parser/ make tests): all test binaries that completed
passed, including the deny, minimize and xtrans suites (tst_regex,
tst_misc, tst_symtab, tst_variable, tst_lib, and tst_interface's
minimize/deny/xtrans cases). The run was not run to completion locally
because the generated equality-matrix test takes very long, but the
baseline behaves the same.
Note this does not address the beta1-era issue (missing mandatory cont-
match stub entirely for conditional inet rules) - that is fixed already
in 5.0.2 - nor the separate legacy net_allowed_af downgrade issue in
update_compat_net() (socket-type mask OR-ed into the deny mask), which
is on a different code path and still open.
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2163740
Title:
net_inet_tcp_fastopen from ubuntu_qrt_apparmor failed on Resolute
To manage notifications about this bug go to:
https://bugs.launchpad.net/apparmor/+bug/2163740/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs