Commit dbb4a0ec authored by Al Viro's avatar Al Viro Committed by Adrian Bunk

[EBTABLES]: Prevent wraparounds in checks for entry components' sizes.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarAdrian Bunk <bunk@stusta.de>
parent e4a7da4a
......@@ -359,10 +359,11 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
{
struct ebt_match *match;
size_t left = ((char *)e + e->watchers_offset) - (char *)m;
int ret;
if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
((char *)e) + e->watchers_offset)
if (left < sizeof(struct ebt_entry_match) ||
left - sizeof(struct ebt_entry_match) < m->match_size)
return -EINVAL;
match = find_match_lock(m->u.name, &ret, &ebt_mutex);
if (!match)
......@@ -388,10 +389,11 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
{
struct ebt_watcher *watcher;
size_t left = ((char *)e + e->target_offset) - (char *)w;
int ret;
if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
((char *)e) + e->target_offset)
if (left < sizeof(struct ebt_entry_watcher) ||
left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
return -EINVAL;
watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
if (!watcher)
......@@ -594,6 +596,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
struct ebt_entry_target *t;
struct ebt_target *target;
unsigned int i, j, hook = 0, hookmask = 0;
size_t gap = e->next_offset - e->target_offset;
int ret;
/* don't mess with the struct ebt_entries */
......@@ -655,8 +658,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
t->u.target = target;
if (t->u.target == &ebt_standard_target) {
if (e->target_offset + sizeof(struct ebt_standard_target) >
e->next_offset) {
if (gap < sizeof(struct ebt_standard_target)) {
BUGPRINT("Standard target size too big\n");
ret = -EFAULT;
goto cleanup_watchers;
......@@ -667,8 +669,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
ret = -EFAULT;
goto cleanup_watchers;
}
} else if ((e->target_offset + t->target_size +
sizeof(struct ebt_entry_target) > e->next_offset) ||
} else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
(t->u.target->check &&
t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
module_put(t->u.target->me);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment