Skip to content

Commit

Permalink
[EBTABLES]: Split ebt_check_entry_size_and_hooks
Browse files Browse the repository at this point in the history
Split ebt_check_entry_size_and_hooks() in two parts - one that does
sanity checks on pointers (basically, checks that we can safely
use iterator from now on) and the rest of it (looking into details
of entry).

The loop applying ebt_check_entry_size_and_hooks() is split in two.

Populating newinfo->hook_entry[] is done in the first part.

Unused arguments killed.

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Al Viro authored and David S. Miller committed Dec 3, 2006
1 parent 14197d5 commit 22b440b
Showing 1 changed file with 49 additions and 24 deletions.
73 changes: 49 additions & 24 deletions net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,11 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
return 0;
}

/*
* this one is very careful, as it is the first function
* to parse the userspace data
*/
static inline int
ebt_check_entry_size_and_hooks(struct ebt_entry *e,
__ebt_verify_pointers(struct ebt_entry *e,
struct ebt_table_info *newinfo, char *base, char *limit,
struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
struct ebt_entries **hook_entries,
unsigned int valid_hooks)
{
unsigned int offset = (char *)e - newinfo->entries;
size_t left = (limit - base) - offset;
Expand All @@ -416,8 +412,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
if ((char *)hook_entries[i] == base + offset)
break;
}
/* beginning of a new chain
if i == NF_BR_NUMHOOKS it must be a user defined chain */
if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
if (e->bitmask != 0) {
/* we make userspace set this right,
Expand All @@ -426,16 +420,52 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
"in distinguisher\n");
return -EINVAL;
}
if (left < sizeof(struct ebt_entries))
goto Esmall;
if (i != NF_BR_NUMHOOKS)
newinfo->hook_entry[i] = (struct ebt_entries *)e;
return 0;
}
if (left < sizeof(struct ebt_entry))
goto Esmall;
if (left < e->next_offset)
goto Esmall;
return 0;

Esmall:
BUGPRINT("entries_size too small\n");
return -EINVAL;
}

/*
* this one is very careful, as it is the first function
* to parse the userspace data
*/
static inline int
ebt_check_entry_size_and_hooks(struct ebt_entry *e,
struct ebt_table_info *newinfo, char *base,
struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
{
unsigned int offset = (char *)e - newinfo->entries;
int i;

for (i = 0; i < NF_BR_NUMHOOKS; i++) {
if ((valid_hooks & (1 << i)) == 0)
continue;
if ((char *)hook_entries[i] == base + offset)
break;
}
/* beginning of a new chain
if i == NF_BR_NUMHOOKS it must be a user defined chain */
if (i != NF_BR_NUMHOOKS || !e->bitmask) {
/* this checks if the previous chain has as many entries
as it said it has */
if (*n != *cnt) {
BUGPRINT("nentries does not equal the nr of entries "
"in the chain\n");
return -EINVAL;
}
/* before we look at the struct, be sure it is not too big */
if (left < sizeof(struct ebt_entries))
goto Esmall;
if (((struct ebt_entries *)e)->policy != EBT_DROP &&
((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
/* only RETURN from udc */
Expand All @@ -447,8 +477,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
}
if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
(*udc_cnt)++;
else
newinfo->hook_entry[i] = (struct ebt_entries *)e;
if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
BUGPRINT("counter_offset != totalcnt");
return -EINVAL;
Expand All @@ -458,8 +486,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
return 0;
}
/* a plain old entry, heh */
if (left < sizeof(struct ebt_entry))
goto Esmall;
if (sizeof(struct ebt_entry) > e->watchers_offset ||
e->watchers_offset > e->target_offset ||
e->target_offset >= e->next_offset) {
Expand All @@ -471,16 +497,9 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
BUGPRINT("target size too small\n");
return -EINVAL;
}
if (left < e->next_offset)
goto Esmall;

(*cnt)++;
(*totalcnt)++;
return 0;

Esmall:
BUGPRINT("entries_size too small\n");
return -EINVAL;
}

struct ebt_cl_stack
Expand Down Expand Up @@ -776,6 +795,12 @@ static int translate_table(struct ebt_replace *repl,
newinfo->entries_size = repl->entries_size;
newinfo->nentries = repl->nentries;

ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
__ebt_verify_pointers, newinfo, repl->entries,
repl->entries + repl->entries_size, repl->hook_entry, repl->valid_hooks);
if (ret != 0)
return ret;

/* do some early checkings and initialize some things */
i = 0; /* holds the expected nr. of entries for the chain */
j = 0; /* holds the up to now counted entries for the chain */
Expand All @@ -784,7 +809,7 @@ static int translate_table(struct ebt_replace *repl,
udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
ebt_check_entry_size_and_hooks, newinfo, repl->entries,
repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
repl->hook_entry, &i, &j, &k,
&udc_cnt, repl->valid_hooks);

if (ret != 0)
Expand Down

0 comments on commit 22b440b

Please sign in to comment.