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

Commit 4c8237cd authored by David S. Miller's avatar David S. Miller
Browse files

ipv4: Validate route entry type at insert instead of every lookup.



fib_semantic_match() requires that if the type doesn't signal an
automatic error, it must be of type RTN_UNICAST, RTN_LOCAL,
RTN_BROADCAST, RTN_ANYCAST, or RTN_MULTICAST.

Checking this every route lookup is pointless work.

Instead validate it during route insertion, via fib_create_info().

Also, there was nothing making sure the type value was less than
RTN_MAX, so add that missing check while we're here.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 256ee435
Loading
Loading
Loading
Loading
+28 −26
Original line number Diff line number Diff line
@@ -707,6 +707,9 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
	int nhs = 1;
	struct net *net = cfg->fc_nlinfo.nl_net;

	if (cfg->fc_type > RTN_MAX)
		goto err_inval;

	/* Fast check to catch the most weird cases */
	if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
		goto err_inval;
@@ -812,6 +815,17 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
		if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
			goto err_inval;
		goto link_it;
	} else {
		switch (cfg->fc_type) {
		case RTN_UNICAST:
		case RTN_LOCAL:
		case RTN_BROADCAST:
		case RTN_ANYCAST:
		case RTN_MULTICAST:
			break;
		default:
			goto err_inval;
		}
	}

	if (cfg->fc_scope > RT_SCOPE_HOST)
@@ -915,12 +929,6 @@ int fib_semantic_match(struct fib_table *tb, struct list_head *head,
			if (fi->fib_flags & RTNH_F_DEAD)
				continue;

			switch (fa->fa_type) {
			case RTN_UNICAST:
			case RTN_LOCAL:
			case RTN_BROADCAST:
			case RTN_ANYCAST:
			case RTN_MULTICAST:
			for_nexthops(fi) {
				if (nh->nh_flags & RTNH_F_DEAD)
					continue;
@@ -938,12 +946,6 @@ int fib_semantic_match(struct fib_table *tb, struct list_head *head,
#endif
			endfor_nexthops(fi);
			continue;

			default:
				pr_warning("fib_semantic_match bad type %#x\n",
					   fa->fa_type);
				return -EINVAL;
			}
		}
		return err;
	}