|
@@ -172,18 +172,35 @@ ebt_among_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool poolsize_invalid(const struct ebt_mac_wormhash *w)
|
|
|
|
+{
|
|
|
|
+ return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple));
|
|
|
|
+}
|
|
|
|
+
|
|
static int ebt_among_mt_check(const struct xt_mtchk_param *par)
|
|
static int ebt_among_mt_check(const struct xt_mtchk_param *par)
|
|
{
|
|
{
|
|
const struct ebt_among_info *info = par->matchinfo;
|
|
const struct ebt_among_info *info = par->matchinfo;
|
|
const struct ebt_entry_match *em =
|
|
const struct ebt_entry_match *em =
|
|
container_of(par->matchinfo, const struct ebt_entry_match, data);
|
|
container_of(par->matchinfo, const struct ebt_entry_match, data);
|
|
- int expected_length = sizeof(struct ebt_among_info);
|
|
|
|
|
|
+ unsigned int expected_length = sizeof(struct ebt_among_info);
|
|
const struct ebt_mac_wormhash *wh_dst, *wh_src;
|
|
const struct ebt_mac_wormhash *wh_dst, *wh_src;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
|
|
+ if (expected_length > em->match_size)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
wh_dst = ebt_among_wh_dst(info);
|
|
wh_dst = ebt_among_wh_dst(info);
|
|
- wh_src = ebt_among_wh_src(info);
|
|
|
|
|
|
+ if (poolsize_invalid(wh_dst))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
expected_length += ebt_mac_wormhash_size(wh_dst);
|
|
expected_length += ebt_mac_wormhash_size(wh_dst);
|
|
|
|
+ if (expected_length > em->match_size)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ wh_src = ebt_among_wh_src(info);
|
|
|
|
+ if (poolsize_invalid(wh_src))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
expected_length += ebt_mac_wormhash_size(wh_src);
|
|
expected_length += ebt_mac_wormhash_size(wh_src);
|
|
|
|
|
|
if (em->match_size != EBT_ALIGN(expected_length)) {
|
|
if (em->match_size != EBT_ALIGN(expected_length)) {
|