Hi list,

During previous research performed on the Linux kernel, we found a vulnerability in the MPTCP subsystem which could lead to a privilege escalation. This vulnerability has been fixed and CVE-2024-57882 has been assigned to it.

The analyze of the patch (https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=cbb26f7d8451fe56ccac802c6db48d16240feebd) reveals that the root cause of the bug has been partially fixed.

The patch wants to ensure the mutual exclusion between the ADD_ADDR and DSS option. It wants to prevent that the establishment of the ADD_ADDR option will not corrupt information about the DSS option previously established. However the check that ensures mutual exclusion is perfomed after the address concerned by the option ADD_ADDR has been set.

static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *skb,
                           unsigned int *size,
                           unsigned int remaining,
                           struct mptcp_out_options *opts)
{
    struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
    struct mptcp_sock *msk = mptcp_sk(subflow->conn);
    bool drop_other_suboptions = false;
    unsigned int opt_size = *size;
    bool echo;
    int len;

    /* add addr will strip the existing options, be sure to avoid breaking
     * MPC/MPJ handshakes
     */
    if (!mptcp_pm_should_add_signal(msk) ||
(opts->suboptions & (OPTION_MPTCP_MPJ_ACK | OPTION_MPTCP_MPC_ACK)) || !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, &opts->addr, <====== [0]
            &echo, &drop_other_suboptions))
        return false;

    /*
     * Later on, mptcp_write_options() will enforce mutually exclusion with
     * DSS, bail out if such option is set and we can't drop it.
     */
    if (drop_other_suboptions)
        remaining += opt_size;
else if (opts->suboptions & OPTION_MPTCP_DSS) <======= [1]
        return false;

    // ...
}

The call to mptcp_pm_add_addr_signal at [0] will modify opts->addr (and corrupt DSS option information) and only after the check for mutual exclusion is done at [1].

We submitted a fix that introduces an intermediate variable which has been merged into the stable tree: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2c1f97a52cb827a5f2768e67a9dddffae1ed47ab.

Altough this is a corruption bug, we did not see any security impact from this bug.

Arthur Mongodin
Security researcher at Randorisec

Reply via email to