return 1;
}
+static inline int check_entry(const struct arpt_entry *e)
+{
+ const struct xt_entry_target *t;
+
+ if (!arp_checkentry(&e->arp))
+ return -EINVAL;
+
+ if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
+ return -EINVAL;
+
+ t = arpt_get_target_c(e);
+ if (e->target_offset + t->u.target_size > e->next_offset)
+ return -EINVAL;
+
+ return 0;
+}
+
static inline int check_target(struct arpt_entry *e, const char *name)
{
struct xt_entry_target *t = arpt_get_target(e);
return -EINVAL;
}
- if (!arp_checkentry(&e->arp))
- 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 (!arp_checkentry(&e->arp))
- return -EINVAL;
+ /* For purposes of check_entry casting the compat entry is fine */
+ ret = check_entry((struct arpt_entry *)e);
- ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
- e->next_offset);
if (ret)
return ret;