memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0;
}
+
static inline const struct xt_entry_target *
ip6t_get_target_c(const struct ip6t_entry *e)
{
module_put(par.match->me);
}
+static int
+check_entry(const struct ip6t_entry *e)
+{
+ const struct xt_entry_target *t;
+
+ if (!ip6_checkentry(&e->ipv6))
+ return -EINVAL;
+
+ if (e->target_offset + sizeof(struct xt_entry_target) >
+ e->next_offset)
+ return -EINVAL;
+
+ t = ip6t_get_target_c(e);
+ if (e->target_offset + t->u.target_size > e->next_offset)
+ return -EINVAL;
+
+ return 0;
+}
+
static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ip6t_ip6 *ipv6 = par->entryinfo;
return -EINVAL;
}
- if (!ip6_checkentry(&e->ipv6))
- return -EINVAL;
+ err = check_entry(e);
- err = xt_check_entry_offsets(e, e->elems, e->target_offset,
- e->next_offset);
if (err)
return err;
return -EINVAL;
}
- if (!ip6_checkentry(&e->ipv6))
- return -EINVAL;
+ /* For purposes of check_entry casting the compat entry is fine */
+ ret = check_entry((struct ip6t_entry *)e);
- ret = xt_compat_check_entry_offsets(e, e->elems,
- e->target_offset, e->next_offset);
if (ret)
return ret;