mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Merge branch 'mptcp-prevent-mpc-handshake-on-port-based-signal-endpoints'
Matthieu Baerts says: ==================== mptcp: prevent MPC handshake on port-based signal endpoints MPTCP connection requests toward a listening socket created by the in-kernel PM for a port based signal endpoint will never be accepted, they need to be explicitly rejected. - Patch 1: Explicitly reject such requests. A fix for >= v5.12. - Patch 2: Cover this case in the MPTCP selftests to avoid regressions. Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> v1: https://lore.kernel.org/20240908180620.822579-1-xiyou.wangcong@gmail.com Link: https://lore.kernel.org/a5289a0d-2557-40b8-9575-6f1a0bbf06e4@redhat.com ==================== Link: https://patch.msgid.link/20241014-net-mptcp-mpc-port-endp-v2-0-7faea8e6b6ae@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
56f51dfdff
@ -17,6 +17,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
|
||||
SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
|
||||
SNMP_MIB_ITEM("MPCapableSYNTXDrop", MPTCP_MIB_MPCAPABLEACTIVEDROP),
|
||||
SNMP_MIB_ITEM("MPCapableSYNTXDisabled", MPTCP_MIB_MPCAPABLEACTIVEDISABLED),
|
||||
SNMP_MIB_ITEM("MPCapableEndpAttempt", MPTCP_MIB_MPCAPABLEENDPATTEMPT),
|
||||
SNMP_MIB_ITEM("MPFallbackTokenInit", MPTCP_MIB_TOKENFALLBACKINIT),
|
||||
SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
|
||||
SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
|
||||
|
@ -12,6 +12,7 @@ enum linux_mptcp_mib_field {
|
||||
MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
|
||||
MPTCP_MIB_MPCAPABLEACTIVEDROP, /* Client-side fallback due to a MPC drop */
|
||||
MPTCP_MIB_MPCAPABLEACTIVEDISABLED, /* Client-side disabled due to past issues */
|
||||
MPTCP_MIB_MPCAPABLEENDPATTEMPT, /* Prohibited MPC to port-based endp */
|
||||
MPTCP_MIB_TOKENFALLBACKINIT, /* Could not init/allocate token */
|
||||
MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */
|
||||
MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */
|
||||
|
@ -1121,6 +1121,7 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
|
||||
*/
|
||||
inet_sk_state_store(newsk, TCP_LISTEN);
|
||||
lock_sock(ssk);
|
||||
WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
|
||||
err = __inet_listen_sk(ssk, backlog);
|
||||
if (!err)
|
||||
mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
|
||||
|
@ -535,6 +535,7 @@ struct mptcp_subflow_context {
|
||||
__unused : 8;
|
||||
bool data_avail;
|
||||
bool scheduled;
|
||||
bool pm_listener; /* a listener managed by the kernel PM? */
|
||||
u32 remote_nonce;
|
||||
u64 thmac;
|
||||
u32 local_nonce;
|
||||
|
@ -132,6 +132,13 @@ static void subflow_add_reset_reason(struct sk_buff *skb, u8 reason)
|
||||
}
|
||||
}
|
||||
|
||||
static int subflow_reset_req_endp(struct request_sock *req, struct sk_buff *skb)
|
||||
{
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEENDPATTEMPT);
|
||||
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Init mptcp request socket.
|
||||
*
|
||||
* Returns an error code if a JOIN has failed and a TCP reset
|
||||
@ -165,6 +172,8 @@ static int subflow_check_req(struct request_sock *req,
|
||||
if (opt_mp_capable) {
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
|
||||
|
||||
if (unlikely(listener->pm_listener))
|
||||
return subflow_reset_req_endp(req, skb);
|
||||
if (opt_mp_join)
|
||||
return 0;
|
||||
} else if (opt_mp_join) {
|
||||
@ -172,6 +181,8 @@ static int subflow_check_req(struct request_sock *req,
|
||||
|
||||
if (mp_opt.backup)
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNBACKUPRX);
|
||||
} else if (unlikely(listener->pm_listener)) {
|
||||
return subflow_reset_req_endp(req, skb);
|
||||
}
|
||||
|
||||
if (opt_mp_capable && listener->request_mptcp) {
|
||||
|
@ -23,6 +23,7 @@ tmpfile=""
|
||||
cout=""
|
||||
err=""
|
||||
capout=""
|
||||
cappid=""
|
||||
ns1=""
|
||||
ns2=""
|
||||
iptables="iptables"
|
||||
@ -887,6 +888,44 @@ check_cestab()
|
||||
fi
|
||||
}
|
||||
|
||||
cond_start_capture()
|
||||
{
|
||||
local ns="$1"
|
||||
|
||||
:> "$capout"
|
||||
|
||||
if $capture; then
|
||||
local capuser capfile
|
||||
if [ -z $SUDO_USER ]; then
|
||||
capuser=""
|
||||
else
|
||||
capuser="-Z $SUDO_USER"
|
||||
fi
|
||||
|
||||
capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "$ns")
|
||||
|
||||
echo "Capturing traffic for test $MPTCP_LIB_TEST_COUNTER into $capfile"
|
||||
ip netns exec "$ns" tcpdump -i any -s 65535 -B 32768 $capuser -w "$capfile" > "$capout" 2>&1 &
|
||||
cappid=$!
|
||||
|
||||
sleep 1
|
||||
fi
|
||||
}
|
||||
|
||||
cond_stop_capture()
|
||||
{
|
||||
if $capture; then
|
||||
sleep 1
|
||||
kill $cappid
|
||||
cat "$capout"
|
||||
fi
|
||||
}
|
||||
|
||||
get_port()
|
||||
{
|
||||
echo "$((10000 + MPTCP_LIB_TEST_COUNTER - 1))"
|
||||
}
|
||||
|
||||
do_transfer()
|
||||
{
|
||||
local listener_ns="$1"
|
||||
@ -894,33 +933,17 @@ do_transfer()
|
||||
local cl_proto="$3"
|
||||
local srv_proto="$4"
|
||||
local connect_addr="$5"
|
||||
local port
|
||||
|
||||
local port=$((10000 + MPTCP_LIB_TEST_COUNTER - 1))
|
||||
local cappid
|
||||
local FAILING_LINKS=${FAILING_LINKS:-""}
|
||||
local fastclose=${fastclose:-""}
|
||||
local speed=${speed:-"fast"}
|
||||
port=$(get_port)
|
||||
|
||||
:> "$cout"
|
||||
:> "$sout"
|
||||
:> "$capout"
|
||||
|
||||
if $capture; then
|
||||
local capuser
|
||||
if [ -z $SUDO_USER ] ; then
|
||||
capuser=""
|
||||
else
|
||||
capuser="-Z $SUDO_USER"
|
||||
fi
|
||||
|
||||
capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "${listener_ns}")
|
||||
|
||||
echo "Capturing traffic for test $MPTCP_LIB_TEST_COUNTER into $capfile"
|
||||
ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
|
||||
cappid=$!
|
||||
|
||||
sleep 1
|
||||
fi
|
||||
cond_start_capture ${listener_ns}
|
||||
|
||||
NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
|
||||
nstat -n
|
||||
@ -1007,10 +1030,7 @@ do_transfer()
|
||||
wait $spid
|
||||
local rets=$?
|
||||
|
||||
if $capture; then
|
||||
sleep 1
|
||||
kill $cappid
|
||||
fi
|
||||
cond_stop_capture
|
||||
|
||||
NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
|
||||
nstat | grep Tcp > /tmp/${listener_ns}.out
|
||||
@ -1026,7 +1046,6 @@ do_transfer()
|
||||
ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
|
||||
cat /tmp/${connector_ns}.out
|
||||
|
||||
cat "$capout"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@ -1043,13 +1062,7 @@ do_transfer()
|
||||
fi
|
||||
rets=$?
|
||||
|
||||
if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
|
||||
cat "$capout"
|
||||
return 0
|
||||
fi
|
||||
|
||||
cat "$capout"
|
||||
return 1
|
||||
[ $retc -eq 0 ] && [ $rets -eq 0 ]
|
||||
}
|
||||
|
||||
make_file()
|
||||
@ -2873,6 +2886,32 @@ verify_listener_events()
|
||||
fail_test
|
||||
}
|
||||
|
||||
chk_mpc_endp_attempt()
|
||||
{
|
||||
local retl=$1
|
||||
local attempts=$2
|
||||
|
||||
print_check "Connect"
|
||||
|
||||
if [ ${retl} = 124 ]; then
|
||||
fail_test "timeout on connect"
|
||||
elif [ ${retl} = 0 ]; then
|
||||
fail_test "unexpected successful connect"
|
||||
else
|
||||
print_ok
|
||||
|
||||
print_check "Attempts"
|
||||
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPCapableEndpAttempt")
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif [ "$count" != "$attempts" ]; then
|
||||
fail_test "got ${count} MPC attempt[s] on port-based endpoint, expected ${attempts}"
|
||||
else
|
||||
print_ok
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_addr_ports_tests()
|
||||
{
|
||||
# signal address with port
|
||||
@ -2963,6 +3002,22 @@ add_addr_ports_tests()
|
||||
chk_join_nr 2 2 2
|
||||
chk_add_nr 2 2 2
|
||||
fi
|
||||
|
||||
if reset "port-based signal endpoint must not accept mpc"; then
|
||||
local port retl count
|
||||
port=$(get_port)
|
||||
|
||||
cond_start_capture ${ns1}
|
||||
pm_nl_add_endpoint ${ns1} 10.0.2.1 flags signal port ${port}
|
||||
mptcp_lib_wait_local_port_listen ${ns1} ${port}
|
||||
|
||||
timeout 1 ip netns exec ${ns2} \
|
||||
./mptcp_connect -t ${timeout_poll} -p $port -s MPTCP 10.0.2.1 >/dev/null 2>&1
|
||||
retl=$?
|
||||
cond_stop_capture
|
||||
|
||||
chk_mpc_endp_attempt ${retl} 1
|
||||
fi
|
||||
}
|
||||
|
||||
syncookies_tests()
|
||||
|
Loading…
Reference in New Issue
Block a user