Commit a9993591 authored by Sriram Yagnaraman's avatar Sriram Yagnaraman Committed by Pablo Neira Ayuso

netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE

RFC 9260, Sec 8.5.1 states that for ABORT/SHUTDOWN_COMPLETE, the chunk
MUST be accepted if the vtag of the packet matches its own tag and the
T bit is not set OR if it is set to its peer's vtag and the T bit is set
in chunk flags. Otherwise the packet MUST be silently dropped.

Update vtag verification for ABORT/SHUTDOWN_COMPLETE based on the above
description.

Fixes: 9fb9cbb1 ("[NETFILTER]: Add nf_conntrack subsystem.")
Signed-off-by: default avatarSriram Yagnaraman <sriram.yagnaraman@est.tech>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 208a2110
...@@ -424,22 +424,29 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, ...@@ -424,22 +424,29 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
/* Special cases of Verification tag check (Sec 8.5.1) */ /* Special cases of Verification tag check (Sec 8.5.1) */
if (sch->type == SCTP_CID_INIT) { if (sch->type == SCTP_CID_INIT) {
/* Sec 8.5.1 (A) */ /* (A) vtag MUST be zero */
if (sh->vtag != 0) if (sh->vtag != 0)
goto out_unlock; goto out_unlock;
} else if (sch->type == SCTP_CID_ABORT) { } else if (sch->type == SCTP_CID_ABORT) {
/* Sec 8.5.1 (B) */ /* (B) vtag MUST match own vtag if T flag is unset OR
if (sh->vtag != ct->proto.sctp.vtag[dir] && * MUST match peer's vtag if T flag is set
sh->vtag != ct->proto.sctp.vtag[!dir]) */
if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
sh->vtag != ct->proto.sctp.vtag[dir]) ||
((sch->flags & SCTP_CHUNK_FLAG_T) &&
sh->vtag != ct->proto.sctp.vtag[!dir]))
goto out_unlock; goto out_unlock;
} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) { } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
/* Sec 8.5.1 (C) */ /* (C) vtag MUST match own vtag if T flag is unset OR
if (sh->vtag != ct->proto.sctp.vtag[dir] && * MUST match peer's vtag if T flag is set
sh->vtag != ct->proto.sctp.vtag[!dir] && */
sch->flags & SCTP_CHUNK_FLAG_T) if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
sh->vtag != ct->proto.sctp.vtag[dir]) ||
((sch->flags & SCTP_CHUNK_FLAG_T) &&
sh->vtag != ct->proto.sctp.vtag[!dir]))
goto out_unlock; goto out_unlock;
} else if (sch->type == SCTP_CID_COOKIE_ECHO) { } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
/* Sec 8.5.1 (D) */ /* (D) vtag must be same as init_vtag as found in INIT_ACK */
if (sh->vtag != ct->proto.sctp.vtag[dir]) if (sh->vtag != ct->proto.sctp.vtag[dir])
goto out_unlock; goto out_unlock;
} else if (sch->type == SCTP_CID_HEARTBEAT) { } else if (sch->type == SCTP_CID_HEARTBEAT) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment