Changelog in Linux kernel 6.19.8

 
apparmor: fix differential encoding verification [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Fri Oct 17 01:53:00 2025 -0700

    apparmor: fix differential encoding verification
    
    commit 39440b137546a3aa383cfdabc605fb73811b6093 upstream.
    
    Differential encoding allows loops to be created if it is abused. To
    prevent this the unpack should verify that a diff-encode chain
    terminates.
    
    Unfortunately the differential encode verification had two bugs.
    
    1. it conflated states that had gone through check and already been
       marked, with states that were currently being checked and marked.
       This means that loops in the current chain being verified are treated
       as a chain that has already been verified.
    
    2. the order bailout on already checked states compared current chain
       check iterators j,k instead of using the outer loop iterator i.
       Meaning a step backwards in states in the current chain verification
       was being mistaken for moving to an already verified state.
    
    Move to a double mark scheme where already verified states get a
    different mark, than the current chain being kept. This enables us
    to also drop the backwards verification check that was the cause of
    the second error as any already verified state is already marked.
    
    Fixes: 031dcc8f4e84 ("apparmor: dfa add support for state differential encoding")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: Fix double free of ns_name in aa_replace_profiles() [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Wed Sep 10 06:22:17 2025 -0700

    apparmor: Fix double free of ns_name in aa_replace_profiles()
    
    commit 5df0c44e8f5f619d3beb871207aded7c78414502 upstream.
    
    if ns_name is NULL after
    1071         error = aa_unpack(udata, &lh, &ns_name);
    
    and if ent->ns_name contains an ns_name in
    1089                 } else if (ent->ns_name) {
    
    then ns_name is assigned the ent->ns_name
    1095                         ns_name = ent->ns_name;
    
    however ent->ns_name is freed at
    1262                 aa_load_ent_free(ent);
    
    and then again when freeing ns_name at
    1270         kfree(ns_name);
    
    Fix this by NULLing out ent->ns_name after it is transferred to ns_name
    
    Fixes: 145a0ef21c8e9 ("apparmor: fix blob compression when ns is forced on a policy load
    ")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix memory leak in verify_header [+ + +]
Author: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Date:   Tue Jan 20 15:24:04 2026 +0100

    apparmor: fix memory leak in verify_header
    
    commit e38c55d9f834e5b848bfed0f5c586aaf45acb825 upstream.
    
    The function sets `*ns = NULL` on every call, leaking the namespace
    string allocated in previous iterations when multiple profiles are
    unpacked. This also breaks namespace consistency checking since *ns
    is always NULL when the comparison is made.
    
    Remove the incorrect assignment.
    The caller (aa_unpack) initializes *ns to NULL once before the loop,
    which is sufficient.
    
    Fixes: dd51c8485763 ("apparmor: provide base for multiple profiles to be replaced at once")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix missing bounds check on DEFAULT table in verify_dfa() [+ + +]
Author: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Date:   Thu Jan 29 16:51:11 2026 +0100

    apparmor: fix missing bounds check on DEFAULT table in verify_dfa()
    
    commit d352873bbefa7eb39995239d0b44ccdf8aaa79a4 upstream.
    
    The verify_dfa() function only checks DEFAULT_TABLE bounds when the state
    is not differentially encoded.
    
    When the verification loop traverses the differential encoding chain,
    it reads k = DEFAULT_TABLE[j] and uses k as an array index without
    validation. A malformed DFA with DEFAULT_TABLE[j] >= state_count,
    therefore, causes both out-of-bounds reads and writes.
    
    [   57.179855] ==================================================================
    [   57.180549] BUG: KASAN: slab-out-of-bounds in verify_dfa+0x59a/0x660
    [   57.180904] Read of size 4 at addr ffff888100eadec4 by task su/993
    
    [   57.181554] CPU: 1 UID: 0 PID: 993 Comm: su Not tainted 6.19.0-rc7-next-20260127 #1 PREEMPT(lazy)
    [   57.181558] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
    [   57.181563] Call Trace:
    [   57.181572]  <TASK>
    [   57.181577]  dump_stack_lvl+0x5e/0x80
    [   57.181596]  print_report+0xc8/0x270
    [   57.181605]  ? verify_dfa+0x59a/0x660
    [   57.181608]  kasan_report+0x118/0x150
    [   57.181620]  ? verify_dfa+0x59a/0x660
    [   57.181623]  verify_dfa+0x59a/0x660
    [   57.181627]  aa_dfa_unpack+0x1610/0x1740
    [   57.181629]  ? __kmalloc_cache_noprof+0x1d0/0x470
    [   57.181640]  unpack_pdb+0x86d/0x46b0
    [   57.181647]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   57.181653]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   57.181656]  ? aa_unpack_nameX+0x1a8/0x300
    [   57.181659]  aa_unpack+0x20b0/0x4c30
    [   57.181662]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   57.181664]  ? stack_depot_save_flags+0x33/0x700
    [   57.181681]  ? kasan_save_track+0x4f/0x80
    [   57.181683]  ? kasan_save_track+0x3e/0x80
    [   57.181686]  ? __kasan_kmalloc+0x93/0xb0
    [   57.181688]  ? __kvmalloc_node_noprof+0x44a/0x780
    [   57.181693]  ? aa_simple_write_to_buffer+0x54/0x130
    [   57.181697]  ? policy_update+0x154/0x330
    [   57.181704]  aa_replace_profiles+0x15a/0x1dd0
    [   57.181707]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   57.181710]  ? __kvmalloc_node_noprof+0x44a/0x780
    [   57.181712]  ? aa_loaddata_alloc+0x77/0x140
    [   57.181715]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   57.181717]  ? _copy_from_user+0x2a/0x70
    [   57.181730]  policy_update+0x17a/0x330
    [   57.181733]  profile_replace+0x153/0x1a0
    [   57.181735]  ? rw_verify_area+0x93/0x2d0
    [   57.181740]  vfs_write+0x235/0xab0
    [   57.181745]  ksys_write+0xb0/0x170
    [   57.181748]  do_syscall_64+0x8e/0x660
    [   57.181762]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
    [   57.181765] RIP: 0033:0x7f6192792eb2
    
    Remove the MATCH_FLAG_DIFF_ENCODE condition to validate all DEFAULT_TABLE
    entries unconditionally.
    
    Fixes: 031dcc8f4e84 ("apparmor: dfa add support for state differential encoding")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix race between freeing data and fs accessing it [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Sun Mar 1 16:10:51 2026 -0800

    apparmor: fix race between freeing data and fs accessing it
    
    commit 8e135b8aee5a06c52a4347a5a6d51223c6f36ba3 upstream.
    
    AppArmor was putting the reference to i_private data on its end after
    removing the original entry from the file system. However the inode
    can aand does live beyond that point and it is possible that some of
    the fs call back functions will be invoked after the reference has
    been put, which results in a race between freeing the data and
    accessing it through the fs.
    
    While the rawdata/loaddata is the most likely candidate to fail the
    race, as it has the fewest references. If properly crafted it might be
    possible to trigger a race for the other types stored in i_private.
    
    Fix this by moving the put of i_private referenced data to the correct
    place which is during inode eviction.
    
    Fixes: c961ee5f21b20 ("apparmor: convert from securityfs to apparmorfs for policy ns files")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Maxime Bélair <maxime.belair@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix race on rawdata dereference [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Tue Feb 24 10:20:02 2026 -0800

    apparmor: fix race on rawdata dereference
    
    commit a0b7091c4de45a7325c8780e6934a894f92ac86b upstream.
    
    There is a race condition that leads to a use-after-free situation:
    because the rawdata inodes are not refcounted, an attacker can start
    open()ing one of the rawdata files, and at the same time remove the
    last reference to this rawdata (by removing the corresponding profile,
    for example), which frees its struct aa_loaddata; as a result, when
    seq_rawdata_open() is reached, i_private is a dangling pointer and
    freed memory is accessed.
    
    The rawdata inodes weren't refcounted to avoid a circular refcount and
    were supposed to be held by the profile rawdata reference.  However
    during profile removal there is a window where the vfs and profile
    destruction race, resulting in the use after free.
    
    Fix this by moving to a double refcount scheme. Where the profile
    refcount on rawdata is used to break the circular dependency. Allowing
    for freeing of the rawdata once all inode references to the rawdata
    are put.
    
    Fixes: 5d5182cae401 ("apparmor: move to per loaddata files, instead of replicating in profiles")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Maxime Bélair <maxime.belair@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix side-effect bug in match_char() macro usage [+ + +]
Author: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Date:   Thu Jan 29 17:08:25 2026 +0100

    apparmor: fix side-effect bug in match_char() macro usage
    
    commit 8756b68edae37ff546c02091989a4ceab3f20abd upstream.
    
    The match_char() macro evaluates its character parameter multiple
    times when traversing differential encoding chains. When invoked
    with *str++, the string pointer advances on each iteration of the
    inner do-while loop, causing the DFA to check different characters
    at each iteration and therefore skip input characters.
    This results in out-of-bounds reads when the pointer advances past
    the input buffer boundary.
    
    [   94.984676] ==================================================================
    [   94.985301] BUG: KASAN: slab-out-of-bounds in aa_dfa_match+0x5ae/0x760
    [   94.985655] Read of size 1 at addr ffff888100342000 by task file/976
    
    [   94.986319] CPU: 7 UID: 1000 PID: 976 Comm: file Not tainted 6.19.0-rc7-next-20260127 #1 PREEMPT(lazy)
    [   94.986322] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
    [   94.986329] Call Trace:
    [   94.986341]  <TASK>
    [   94.986347]  dump_stack_lvl+0x5e/0x80
    [   94.986374]  print_report+0xc8/0x270
    [   94.986384]  ? aa_dfa_match+0x5ae/0x760
    [   94.986388]  kasan_report+0x118/0x150
    [   94.986401]  ? aa_dfa_match+0x5ae/0x760
    [   94.986405]  aa_dfa_match+0x5ae/0x760
    [   94.986408]  __aa_path_perm+0x131/0x400
    [   94.986418]  aa_path_perm+0x219/0x2f0
    [   94.986424]  apparmor_file_open+0x345/0x570
    [   94.986431]  security_file_open+0x5c/0x140
    [   94.986442]  do_dentry_open+0x2f6/0x1120
    [   94.986450]  vfs_open+0x38/0x2b0
    [   94.986453]  ? may_open+0x1e2/0x2b0
    [   94.986466]  path_openat+0x231b/0x2b30
    [   94.986469]  ? __x64_sys_openat+0xf8/0x130
    [   94.986477]  do_file_open+0x19d/0x360
    [   94.986487]  do_sys_openat2+0x98/0x100
    [   94.986491]  __x64_sys_openat+0xf8/0x130
    [   94.986499]  do_syscall_64+0x8e/0x660
    [   94.986515]  ? count_memcg_events+0x15f/0x3c0
    [   94.986526]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   94.986540]  ? handle_mm_fault+0x1639/0x1ef0
    [   94.986551]  ? vma_start_read+0xf0/0x320
    [   94.986558]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   94.986561]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   94.986563]  ? fpregs_assert_state_consistent+0x50/0xe0
    [   94.986572]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   94.986574]  ? arch_exit_to_user_mode_prepare+0x9/0xb0
    [   94.986587]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   94.986588]  ? irqentry_exit+0x3c/0x590
    [   94.986595]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
    [   94.986597] RIP: 0033:0x7fda4a79c3ea
    
    Fix by extracting the character value before invoking match_char,
    ensuring single evaluation per outer loop.
    
    Fixes: 074c1cd798cb ("apparmor: dfa move character match into a macro")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix unprivileged local user can do privileged policy management [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Fri Nov 7 08:36:04 2025 -0800

    apparmor: fix unprivileged local user can do privileged policy management
    
    commit 6601e13e82841879406bf9f369032656f441a425 upstream.
    
    An unprivileged local user can load, replace, and remove profiles by
    opening the apparmorfs interfaces, via a confused deputy attack, by
    passing the opened fd to a privileged process, and getting the
    privileged process to write to the interface.
    
    This does require a privileged target that can be manipulated to do
    the write for the unprivileged process, but once such access is
    achieved full policy management is possible and all the possible
    implications that implies: removing confinement, DoS of system or
    target applications by denying all execution, by-passing the
    unprivileged user namespace restriction, to exploiting kernel bugs for
    a local privilege escalation.
    
    The policy management interface can not have its permissions simply
    changed from 0666 to 0600 because non-root processes need to be able
    to load policy to different policy namespaces.
    
    Instead ensure the task writing the interface has privileges that
    are a subset of the task that opened the interface. This is already
    done via policy for confined processes, but unconfined can delegate
    access to the opened fd, by-passing the usual policy check.
    
    Fixes: b7fd2c0340eac ("apparmor: add per policy ns .load, .replace, .remove interface files")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: fix: limit the number of levels of policy namespaces [+ + +]
Author: John Johansen <john.johansen@canonical.com>
Date:   Tue Mar 3 11:08:02 2026 -0800

    apparmor: fix: limit the number of levels of policy namespaces
    
    commit 306039414932c80f8420695a24d4fe10c84ccfb2 upstream.
    
    Currently the number of policy namespaces is not bounded relying on
    the user namespace limit. However policy namespaces aren't strictly
    tied to user namespaces and it is possible to create them and nest
    them arbitrarily deep which can be used to exhaust system resource.
    
    Hard cap policy namespaces to the same depth as user namespaces.
    
    Fixes: c88d4c7b049e8 ("AppArmor: core policy routines")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Reviewed-by: Ryan Lee <ryan.lee@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: replace recursive profile removal with iterative approach [+ + +]
Author: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Date:   Tue Jan 13 09:09:43 2026 +0100

    apparmor: replace recursive profile removal with iterative approach
    
    commit ab09264660f9de5d05d1ef4e225aa447c63a8747 upstream.
    
    The profile removal code uses recursion when removing nested profiles,
    which can lead to kernel stack exhaustion and system crashes.
    
    Reproducer:
      $ pf='a'; for ((i=0; i<1024; i++)); do
          echo -e "profile $pf { \n }" | apparmor_parser -K -a;
          pf="$pf//x";
      done
      $ echo -n a > /sys/kernel/security/apparmor/.remove
    
    Replace the recursive __aa_profile_list_release() approach with an
    iterative approach in __remove_profile(). The function repeatedly
    finds and removes leaf profiles until the entire subtree is removed,
    maintaining the same removal semantic without recursion.
    
    Fixes: c88d4c7b049e ("AppArmor: core policy routines")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

apparmor: validate DFA start states are in bounds in unpack_pdb [+ + +]
Author: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Date:   Thu Jan 15 15:30:50 2026 +0100

    apparmor: validate DFA start states are in bounds in unpack_pdb
    
    commit 9063d7e2615f4a7ab321de6b520e23d370e58816 upstream.
    
    Start states are read from untrusted data and used as indexes into the
    DFA state tables. The aa_dfa_next() function call in unpack_pdb() will
    access dfa->tables[YYTD_ID_BASE][start], and if the start state exceeds
    the number of states in the DFA, this results in an out-of-bound read.
    
    ==================================================================
     BUG: KASAN: slab-out-of-bounds in aa_dfa_next+0x2a1/0x360
     Read of size 4 at addr ffff88811956fb90 by task su/1097
     ...
    
    Reject policies with out-of-bounds start states during unpacking
    to prevent the issue.
    
    Fixes: ad5ff3db53c6 ("AppArmor: Add ability to load extended policy")
    Reported-by: Qualys Security Advisory <qsa@qualys.com>
    Tested-by: Salvatore Bonaccorso <carnil@debian.org>
    Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
    Reviewed-by: Cengiz Can <cengiz.can@canonical.com>
    Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
    Signed-off-by: John Johansen <john.johansen@canonical.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

 
Linux: Linux 6.19.8 [+ + +]
Author: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date:   Fri Mar 13 17:26:05 2026 +0100

    Linux 6.19.8
    
    Link: https://lore.kernel.org/r/20260312200321.671986598@linuxfoundation.org
    Tested-by: Brett A C Sheffield <bacs@librecast.net>
    Tested-by: Shuah Khan <skhan@linuxfoundation.org>
    Tested-by: Ronald Warsow <rwarsow@gmx.de>
    Tested-by: Ron Economos <re@w6rz.net>
    Tested-by: Mark Brown <broonie@kernel.org>
    Tested-by: Takeshi Ogasawara <takeshi.ogasawara@futuring-girl.com>
    Tested-by: Jon Hunter <jonathanh@nvidia.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

 
net/sched: act_gate: snapshot parameters with RCU on replace [+ + +]
Author: Paul Moses <p@1g4.org>
Date:   Mon Feb 23 15:05:44 2026 +0000

    net/sched: act_gate: snapshot parameters with RCU on replace
    
    commit 62413a9c3cb183afb9bb6e94dd68caf4e4145f4c upstream.
    
    The gate action can be replaced while the hrtimer callback or dump path is
    walking the schedule list.
    
    Convert the parameters to an RCU-protected snapshot and swap updates under
    tcf_lock, freeing the previous snapshot via call_rcu(). When REPLACE omits
    the entry list, preserve the existing schedule so the effective state is
    unchanged.
    
    Fixes: a51c328df310 ("net: qos: introduce a gate control flow action")
    Cc: stable@vger.kernel.org
    Signed-off-by: Paul Moses <p@1g4.org>
    Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
    Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
    Reviewed-by: Victor Nogueira <victor@mojatatu.com>
    Link: https://patch.msgid.link/20260223150512.2251594-2-p@1g4.org
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks [+ + +]
Author: Victor Nogueira <victor@mojatatu.com>
Date:   Wed Feb 25 10:43:48 2026 -0300

    net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks
    
    commit 11cb63b0d1a0685e0831ae3c77223e002ef18189 upstream.
    
    As Paolo said earlier [1]:
    
    "Since the blamed commit below, classify can return TC_ACT_CONSUMED while
    the current skb being held by the defragmentation engine. As reported by
    GangMin Kim, if such packet is that may cause a UaF when the defrag engine
    later on tries to tuch again such packet."
    
    act_ct was never meant to be used in the egress path, however some users
    are attaching it to egress today [2]. Attempting to reach a middle
    ground, we noticed that, while most qdiscs are not handling
    TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we
    address the issue by only allowing act_ct to bind to clsact/ingress
    qdiscs and shared blocks. That way it's still possible to attach act_ct to
    egress (albeit only with clsact).
    
    [1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/
    [2] https://lore.kernel.org/netdev/cc6bfb4a-4a2b-42d8-b9ce-7ef6644fb22b@ovn.org/
    
    Reported-by: GangMin Kim <km.kim1503@gmail.com>
    Fixes: 3f14b377d01d ("net/sched: act_ct: fix skb leak and crash on ooo frags")
    CC: stable@vger.kernel.org
    Signed-off-by: Victor Nogueira <victor@mojatatu.com>
    Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
    Link: https://patch.msgid.link/20260225134349.1287037-1-victor@mojatatu.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>