cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xt_esp.c (2553B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Kernel module to match ESP parameters. */
      3
      4/* (C) 1999-2000 Yon Uriarte <yon@astaro.de>
      5 */
      6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      7#include <linux/module.h>
      8#include <linux/skbuff.h>
      9#include <linux/in.h>
     10#include <linux/ip.h>
     11
     12#include <linux/netfilter/xt_esp.h>
     13#include <linux/netfilter/x_tables.h>
     14
     15#include <linux/netfilter_ipv4/ip_tables.h>
     16#include <linux/netfilter_ipv6/ip6_tables.h>
     17
     18MODULE_LICENSE("GPL");
     19MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
     20MODULE_DESCRIPTION("Xtables: IPsec-ESP packet match");
     21MODULE_ALIAS("ipt_esp");
     22MODULE_ALIAS("ip6t_esp");
     23
     24/* Returns 1 if the spi is matched by the range, 0 otherwise */
     25static inline bool
     26spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
     27{
     28	bool r;
     29	pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
     30		 invert ? '!' : ' ', min, spi, max);
     31	r = (spi >= min && spi <= max) ^ invert;
     32	pr_debug(" result %s\n", r ? "PASS" : "FAILED");
     33	return r;
     34}
     35
     36static bool esp_mt(const struct sk_buff *skb, struct xt_action_param *par)
     37{
     38	const struct ip_esp_hdr *eh;
     39	struct ip_esp_hdr _esp;
     40	const struct xt_esp *espinfo = par->matchinfo;
     41
     42	/* Must not be a fragment. */
     43	if (par->fragoff != 0)
     44		return false;
     45
     46	eh = skb_header_pointer(skb, par->thoff, sizeof(_esp), &_esp);
     47	if (eh == NULL) {
     48		/* We've been asked to examine this packet, and we
     49		 * can't.  Hence, no choice but to drop.
     50		 */
     51		pr_debug("Dropping evil ESP tinygram.\n");
     52		par->hotdrop = true;
     53		return false;
     54	}
     55
     56	return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
     57			 !!(espinfo->invflags & XT_ESP_INV_SPI));
     58}
     59
     60static int esp_mt_check(const struct xt_mtchk_param *par)
     61{
     62	const struct xt_esp *espinfo = par->matchinfo;
     63
     64	if (espinfo->invflags & ~XT_ESP_INV_MASK) {
     65		pr_debug("unknown flags %X\n", espinfo->invflags);
     66		return -EINVAL;
     67	}
     68
     69	return 0;
     70}
     71
     72static struct xt_match esp_mt_reg[] __read_mostly = {
     73	{
     74		.name		= "esp",
     75		.family		= NFPROTO_IPV4,
     76		.checkentry	= esp_mt_check,
     77		.match		= esp_mt,
     78		.matchsize	= sizeof(struct xt_esp),
     79		.proto		= IPPROTO_ESP,
     80		.me		= THIS_MODULE,
     81	},
     82	{
     83		.name		= "esp",
     84		.family		= NFPROTO_IPV6,
     85		.checkentry	= esp_mt_check,
     86		.match		= esp_mt,
     87		.matchsize	= sizeof(struct xt_esp),
     88		.proto		= IPPROTO_ESP,
     89		.me		= THIS_MODULE,
     90	},
     91};
     92
     93static int __init esp_mt_init(void)
     94{
     95	return xt_register_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
     96}
     97
     98static void __exit esp_mt_exit(void)
     99{
    100	xt_unregister_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
    101}
    102
    103module_init(esp_mt_init);
    104module_exit(esp_mt_exit);