cregit-Linux how code gets into the kernel

Release 4.8 net/netfilter/xt_sctp.c

Directory: net/netfilter

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/sctp/sctp.h>
#include <linux/sctp.h>

#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_sctp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kiran Kumar Immidi");
MODULE_DESCRIPTION("Xtables: SCTP protocol packet match");
MODULE_ALIAS("ipt_sctp");
MODULE_ALIAS("ip6t_sctp");


#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
                                              || (!!((invflag) & (option)) ^ (cond)))


static bool match_flags(const struct xt_sctp_flag_info *flag_info, const int flag_count, u_int8_t chunktype, u_int8_t chunkflags) { int i; for (i = 0; i < flag_count; i++) if (flag_info[i].chunktype == chunktype) return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; return true; }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte6997.18%266.67%
jan engelhardtjan engelhardt22.82%133.33%
Total71100.00%3100.00%


static inline bool match_packet(const struct sk_buff *skb, unsigned int offset, const struct xt_sctp_info *info, bool *hotdrop) { u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; const sctp_chunkhdr_t *sch; sctp_chunkhdr_t _sch; int chunk_match_type = info->chunk_match_type; const struct xt_sctp_flag_info *flag_info = info->flag_info; int flag_count = info->flag_count; #ifdef DEBUG int i = 0; #endif if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap); do { sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); if (sch == NULL || sch->length == 0) { pr_debug("Dropping invalid SCTP packet.\n"); *hotdrop = true; return false; } #ifdef DEBUG pr_debug("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d" "\tflags: %x\n", ++i, offset, sch->type, htons(sch->length), sch->flags); #endif offset += WORD_ROUND(ntohs(sch->length)); pr_debug("skb->len: %d\toffset: %d\n", skb->len, offset); if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) { switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ANY: if (match_flags(flag_info, flag_count, sch->type, sch->flags)) { return true; } break; case SCTP_CHUNK_MATCH_ALL: if (match_flags(flag_info, flag_count, sch->type, sch->flags)) SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); break; case SCTP_CHUNK_MATCH_ONLY: if (!match_flags(flag_info, flag_count, sch->type, sch->flags)) return false; break; } } else { switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ONLY: return false; } } } while (offset < skb->len); switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ALL: return SCTP_CHUNKMAP_IS_CLEAR(chunkmapcopy); case SCTP_CHUNK_MATCH_ANY: return false; case SCTP_CHUNK_MATCH_ONLY: return true; } /* This will never be reached, but required to stop compiler whine */ return false; }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte26173.94%216.67%
patrick mchardypatrick mchardy329.07%216.67%
li zefanli zefan308.50%18.33%
jan engelhardtjan engelhardt257.08%433.33%
shan weishan wei30.85%18.33%
qu haoranqu haoran10.28%18.33%
al viroal viro10.28%18.33%
Total353100.00%12100.00%


static bool sctp_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_sctp_info *info = par->matchinfo; const sctp_sctphdr_t *sh; sctp_sctphdr_t _sh; if (par->fragoff != 0) { pr_debug("Dropping non-first fragment.. FIXME\n"); return false; } sh = skb_header_pointer(skb, par->thoff, sizeof(_sh), &_sh); if (sh == NULL) { pr_debug("Dropping evil TCP offset=0 tinygram.\n"); par->hotdrop = true; return false; } pr_debug("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); return SCCHECK(ntohs(sh->source) >= info->spts[0] && ntohs(sh->source) <= info->spts[1], XT_SCTP_SRC_PORTS, info->flags, info->invflags) && SCCHECK(ntohs(sh->dest) >= info->dpts[0] && ntohs(sh->dest) <= info->dpts[1], XT_SCTP_DEST_PORTS, info->flags, info->invflags) && SCCHECK(match_packet(skb, par->thoff + sizeof(sctp_sctphdr_t), info, &par->hotdrop), XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte17174.35%215.38%
jan engelhardtjan engelhardt3213.91%861.54%
patrick mchardypatrick mchardy229.57%215.38%
jorge matiasjorge matias52.17%17.69%
Total230100.00%13100.00%


static int sctp_mt_check(const struct xt_mtchk_param *par) { const struct xt_sctp_info *info = par->matchinfo; if (info->flags & ~XT_SCTP_VALID_FLAGS) return -EINVAL; if (info->invflags & ~XT_SCTP_VALID_FLAGS) return -EINVAL; if (info->invflags & ~info->flags) return -EINVAL; if (!(info->flags & XT_SCTP_CHUNK_TYPES)) return 0; if (info->chunk_match_type & (SCTP_CHUNK_MATCH_ALL | SCTP_CHUNK_MATCH_ANY | SCTP_CHUNK_MATCH_ONLY)) return 0; return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte5455.10%225.00%
jan engelhardtjan engelhardt4242.86%562.50%
patrick mchardypatrick mchardy22.04%112.50%
Total98100.00%8100.00%

static struct xt_match sctp_mt_reg[] __read_mostly = { { .name = "sctp", .family = NFPROTO_IPV4, .checkentry = sctp_mt_check, .match = sctp_mt, .matchsize = sizeof(struct xt_sctp_info), .proto = IPPROTO_SCTP, .me = THIS_MODULE }, { .name = "sctp", .family = NFPROTO_IPV6, .checkentry = sctp_mt_check, .match = sctp_mt, .matchsize = sizeof(struct xt_sctp_info), .proto = IPPROTO_SCTP, .me = THIS_MODULE }, };
static int __init sctp_mt_init(void) { return xt_register_matches(sctp_mt_reg, ARRAY_SIZE(sctp_mt_reg)); }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte1365.00%250.00%
patrick mchardypatrick mchardy420.00%125.00%
jan engelhardtjan engelhardt315.00%125.00%
Total20100.00%4100.00%


static void __exit sctp_mt_exit(void) { xt_unregister_matches(sctp_mt_reg, ARRAY_SIZE(sctp_mt_reg)); }

Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte1263.16%250.00%
patrick mchardypatrick mchardy421.05%125.00%
jan engelhardtjan engelhardt315.79%125.00%
Total19100.00%4100.00%

module_init(sctp_mt_init); module_exit(sctp_mt_exit);

Overall Contributors

PersonTokensPropCommitsCommitProp
harald welteharald welte68270.53%26.90%
jan engelhardtjan engelhardt12913.34%1551.72%
patrick mchardypatrick mchardy11311.69%724.14%
li zefanli zefan303.10%13.45%
shan weishan wei60.62%13.45%
jorge matiasjorge matias50.52%13.45%
qu haoranqu haoran10.10%13.45%
al viroal viro10.10%13.45%
Total967100.00%29100.00%
Directory: net/netfilter
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.