mirror of https://gitee.com/openkylin/linux.git
netfilter: conntrack: validate SCTP crc32c in PREROUTING
implement sctp_error to let nf_conntrack_in validate crc32c on the packet transport header. Assign skb->ip_summed to CHECKSUM_UNNECESSARY and return NF_ACCEPT in case of successful validation; otherwise, return -NF_ACCEPT to let netfilter skip connection tracking, like other protocols do. Besides preventing corrupted packets from matching conntrack entries, this fixes functionality of REJECT target: it was not generating any ICMP upon reception of SCTP packets, because it was computing RFC 1624 checksum on the packet and systematically mismatching crc32c in the SCTP header. Signed-off-by: Davide Caratti <dcaratti@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
300ae14946
commit
cf6e007eef
|
@ -22,7 +22,9 @@
|
|||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <net/sctp/checksum.h>
|
||||
|
||||
#include <net/netfilter/nf_log.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||
#include <net/netfilter/nf_conntrack_ecache.h>
|
||||
|
@ -505,6 +507,34 @@ static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb,
|
||||
unsigned int dataoff, enum ip_conntrack_info *ctinfo,
|
||||
u8 pf, unsigned int hooknum)
|
||||
{
|
||||
const struct sctphdr *sh;
|
||||
struct sctphdr _sctph;
|
||||
const char *logmsg;
|
||||
|
||||
sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
|
||||
if (!sh) {
|
||||
logmsg = "nf_ct_sctp: short packet ";
|
||||
goto out_invalid;
|
||||
}
|
||||
if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
|
||||
skb->ip_summed == CHECKSUM_NONE) {
|
||||
if (sh->checksum != sctp_compute_cksum(skb, dataoff)) {
|
||||
logmsg = "nf_ct_sctp: bad CRC ";
|
||||
goto out_invalid;
|
||||
}
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
return NF_ACCEPT;
|
||||
out_invalid:
|
||||
if (LOG_INVALID(net, IPPROTO_SCTP))
|
||||
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, "%s", logmsg);
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
|
||||
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
@ -752,6 +782,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
|
|||
.packet = sctp_packet,
|
||||
.get_timeouts = sctp_get_timeouts,
|
||||
.new = sctp_new,
|
||||
.error = sctp_error,
|
||||
.me = THIS_MODULE,
|
||||
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
|
||||
.to_nlattr = sctp_to_nlattr,
|
||||
|
@ -786,6 +817,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
|
|||
.packet = sctp_packet,
|
||||
.get_timeouts = sctp_get_timeouts,
|
||||
.new = sctp_new,
|
||||
.error = sctp_error,
|
||||
.me = THIS_MODULE,
|
||||
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
|
||||
.to_nlattr = sctp_to_nlattr,
|
||||
|
|
Loading…
Reference in New Issue