Merge: CVE-2026-31669: mptcp: fix slab-use-after-free in __inet_lookup_established

MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/2479

JIRA: https://redhat.atlassian.net/browse/RHEL-171511
CVE: CVE-2026-31669

```
commit 9b55b253907e7431210483519c5ad711a37dafa1
Author: Jiayuan Chen <jiayuan.chen@linux.dev>
Date:   Mon Apr 6 11:15:10 2026 +0800

    mptcp: fix slab-use-after-free in __inet_lookup_established

    The ehash table lookups are lockless and rely on
    SLAB_TYPESAFE_BY_RCU to guarantee socket memory stability
    during RCU read-side critical sections. Both tcp_prot and
    tcpv6_prot have their slab caches created with this flag
    via proto_register().

    However, MPTCP's mptcp_subflow_init() copies tcpv6_prot into
    tcpv6_prot_override during inet_init() (fs_initcall, level 5),
    before inet6_init() (module_init/device_initcall, level 6) has
    called proto_register(&tcpv6_prot). At that point,
    tcpv6_prot.slab is still NULL, so tcpv6_prot_override.slab
    remains NULL permanently.

    This causes MPTCP v6 subflow child sockets to be allocated via
    kmalloc (falling into kmalloc-4k) instead of the TCPv6 slab
    cache. The kmalloc-4k cache lacks SLAB_TYPESAFE_BY_RCU, so
    when these sockets are freed without SOCK_RCU_FREE (which is
    cleared for child sockets by design), the memory can be
    immediately reused. Concurrent ehash lookups under
    rcu_read_lock can then access freed memory, triggering a
    slab-use-after-free in __inet_lookup_established.

    Fix this by splitting the IPv6-specific initialization out of
    mptcp_subflow_init() into a new mptcp_subflow_v6_init(), called
    from mptcp_proto_v6_init() before protocol registration. This
    ensures tcpv6_prot_override.slab correctly inherits the
    SLAB_TYPESAFE_BY_RCU slab cache.

    Fixes: b19bc2945b ("mptcp: implement delegated actions")
    Cc: stable@vger.kernel.org
    Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
    Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
    Link: https://patch.msgid.link/20260406031512.189159-1-jiayuan.chen@linux.dev
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
```

Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
[^footer]: Created 2026-04-28 12:12 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://redhat.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=12334433&issuetype=1&priority=4&summary=backporter+webhook+issue&components=kernel-workflow+/+backporter) [^footer]

Approved-by: Paolo Abeni <pabeni@redhat.com>
Approved-by: Davide Caratti <dcaratti@redhat.com>
Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com>

Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
CKI KWF Bot
2026-08-23 18:50:42 +00:00
3 changed files with 12 additions and 6 deletions
+2
View File
@@ -4203,6 +4203,8 @@ int __init mptcp_proto_v6_init(void)
{
int err;
mptcp_subflow_v6_init();
mptcp_v6_prot = mptcp_prot;
strscpy(mptcp_v6_prot.name, "MPTCPv6", sizeof(mptcp_v6_prot.name));
mptcp_v6_prot.slab = NULL;
+1
View File
@@ -817,6 +817,7 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
void __init mptcp_proto_init(void);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
int __init mptcp_proto_v6_init(void);
void __init mptcp_subflow_v6_init(void);
#endif
struct sock *mptcp_sk_clone_init(const struct sock *sk,
+9 -6
View File
@@ -2151,7 +2151,15 @@ void __init mptcp_subflow_init(void)
tcp_prot_override.psock_update_sk_prot = NULL;
#endif
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
void __init mptcp_subflow_v6_init(void)
{
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
* structures for v4 and v6 have the same size. It should not changed in
* the future but better to make sure to be warned if it is no longer
@@ -2190,10 +2198,5 @@ void __init mptcp_subflow_init(void)
/* Disable sockmap processing for subflows */
tcpv6_prot_override.psock_update_sk_prot = NULL;
#endif
#endif
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#endif