Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f939713 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: Convert ip6_tables matches/targets to centralized error checking

parent aa83c1ab
Loading
Loading
Loading
Loading
+7 −16
Original line number Diff line number Diff line
@@ -544,21 +544,12 @@ standard_check(const struct ip6t_entry_target *t,
	struct ip6t_standard_target *targ = (void *)t;

	/* Check standard info. */
	if (t->u.target_size
	    != IP6T_ALIGN(sizeof(struct ip6t_standard_target))) {
		duprintf("standard_check: target size %u != %u\n",
			 t->u.target_size,
			 IP6T_ALIGN(sizeof(struct ip6t_standard_target)));
		return 0;
	}

	if (targ->verdict >= 0
	    && targ->verdict > max_offset - sizeof(struct ip6t_entry)) {
		duprintf("ip6t_standard_check: bad verdict (%i)\n",
			 targ->verdict);
		return 0;
	}

	if (targ->verdict < -NF_MAX_VERDICT - 1) {
		duprintf("ip6t_standard_check: bad negative verdict (%i)\n",
			 targ->verdict);
@@ -1385,24 +1376,22 @@ icmp6_checkentry(const char *tablename,
	   unsigned int matchsize,
	   unsigned int hook_mask)
{
	const struct ip6t_ip6 *ipv6 = entry;
	const struct ip6t_icmp *icmpinfo = matchinfo;

	/* Must specify proto == ICMP, and no unknown invflags */
	return ipv6->proto == IPPROTO_ICMPV6
		&& !(ipv6->invflags & IP6T_INV_PROTO)
		&& matchsize == IP6T_ALIGN(sizeof(struct ip6t_icmp))
		&& !(icmpinfo->invflags & ~IP6T_ICMP_INV);
	/* Must specify no unknown invflags */
	return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
}

/* The built-in targets: standard (NULL) and error. */
static struct ip6t_target ip6t_standard_target = {
	.name		= IP6T_STANDARD_TARGET,
	.targetsize	= sizeof(int),
};

static struct ip6t_target ip6t_error_target = {
	.name		= IP6T_ERROR_TARGET,
	.target		= ip6t_error,
	.targetsize	= IP6T_FUNCTION_MAXNAMELEN,
};

static struct nf_sockopt_ops ip6t_sockopts = {
@@ -1418,7 +1407,9 @@ static struct nf_sockopt_ops ip6t_sockopts = {
static struct ip6t_match icmp6_matchstruct = {
	.name		= "icmp6",
	.match		= &icmp6_match,
	.checkentry	= &icmp6_checkentry,
	.matchsize	= sizeof(struct ip6t_icmp),
	.checkentry	= icmp6_checkentry,
	.proto		= IPPROTO_ICMPV6,
};

static int __init init(void)
+2 −15
Original line number Diff line number Diff line
@@ -69,37 +69,24 @@ static int ip6t_hl_checkentry(const char *tablename,
{
	struct ip6t_HL_info *info = targinfo;

	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
		printk(KERN_WARNING "ip6t_HL: targinfosize %u != %Zu\n",
				targinfosize,
				IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
		return 0;	
	}	

	if (strcmp(tablename, "mangle")) {
		printk(KERN_WARNING "ip6t_HL: can only be called from "
			"\"mangle\" table, not \"%s\"\n", tablename);
		return 0;
	}

	if (info->mode > IP6T_HL_MAXMODE) {
		printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", 
			info->mode);
		return 0;
	}

	if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
		printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
			"make sense with value 0\n");
		return 0;
	}
	
	return 1;
}

static struct ip6t_target ip6t_HL = { 
	.name 		= "HL", 
	.target		= ip6t_hl_target, 
	.targetsize	= sizeof(struct ip6t_HL_info),
	.table		= "mangle",
	.checkentry	= ip6t_hl_checkentry, 
	.me		= THIS_MODULE
};
+1 −8
Original line number Diff line number Diff line
@@ -455,29 +455,22 @@ static int ip6t_log_checkentry(const char *tablename,
{
	const struct ip6t_log_info *loginfo = targinfo;

	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_log_info))) {
		DEBUGP("LOG: targinfosize %u != %u\n",
		       targinfosize, IP6T_ALIGN(sizeof(struct ip6t_log_info)));
		return 0;
	}

	if (loginfo->level >= 8) {
		DEBUGP("LOG: level %u >= 8\n", loginfo->level);
		return 0;
	}

	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
		DEBUGP("LOG: prefix term %i\n",
		       loginfo->prefix[sizeof(loginfo->prefix)-1]);
		return 0;
	}

	return 1;
}

static struct ip6t_target ip6t_log_reg = {
	.name 		= "LOG",
	.target 	= ip6t_log_target, 
	.targetsize	= sizeof(struct ip6t_log_info),
	.checkentry	= ip6t_log_checkentry, 
	.me 		= THIS_MODULE,
};
+4 −19
Original line number Diff line number Diff line
@@ -228,24 +228,6 @@ static int check(const char *tablename,
 	const struct ip6t_reject_info *rejinfo = targinfo;
	const struct ip6t_entry *e = entry;

 	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
  		DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
  		return 0;
  	}

	/* Only allow these for packet filtering. */
	if (strcmp(tablename, "filter") != 0) {
		DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
		return 0;
	}

	if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
			   | (1 << NF_IP6_FORWARD)
			   | (1 << NF_IP6_LOCAL_OUT))) != 0) {
		DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
		return 0;
	}

	if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
		printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
		return 0;
@@ -257,13 +239,16 @@ static int check(const char *tablename,
			return 0;
		}
	}

	return 1;
}

static struct ip6t_target ip6t_reject_reg = {
	.name		= "REJECT",
	.target		= reject6_target,
	.targetsize	= sizeof(struct ip6t_reject_info),
	.table		= "filter",
	.hooks		= (1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) |
			  (1 << NF_IP6_LOCAL_OUT),
	.checkentry	= check,
	.me		= THIS_MODULE
};
+3 −7
Original line number Diff line number Diff line
@@ -105,11 +105,6 @@ checkentry(const char *tablename,
{
	const struct ip6t_ah *ahinfo = matchinfo;

	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_ah))) {
		DEBUGP("ip6t_ah: matchsize %u != %u\n",
		       matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_ah)));
		return 0;
	}
	if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
		DEBUGP("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
		return 0;
@@ -119,8 +114,9 @@ checkentry(const char *tablename,

static struct ip6t_match ah_match = {
	.name		= "ah",
	.match		= &match,
	.checkentry	= &checkentry,
	.match		= match,
	.matchsize	= sizeof(struct ip6t_ah),
	.checkentry	= checkentry,
	.me		= THIS_MODULE,
};

Loading