mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 02:04:19 +08:00
netfilter: arp_tables: simplify translate_compat_table args
Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
329a080712
commit
8dddd32756
@ -1214,6 +1214,18 @@ static int do_add_counters(struct net *net, const void __user *user,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_arpt_replace {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
u32 valid_hooks;
|
||||
u32 num_entries;
|
||||
u32 size;
|
||||
u32 hook_entry[NF_ARP_NUMHOOKS];
|
||||
u32 underflow[NF_ARP_NUMHOOKS];
|
||||
u32 num_counters;
|
||||
compat_uptr_t counters;
|
||||
struct compat_arpt_entry entries[0];
|
||||
};
|
||||
|
||||
static inline void compat_release_entry(struct compat_arpt_entry *e)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
@ -1229,8 +1241,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
|
||||
const unsigned char *base,
|
||||
const unsigned char *limit,
|
||||
const unsigned int *hook_entries,
|
||||
const unsigned int *underflows,
|
||||
const char *name)
|
||||
const unsigned int *underflows)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
struct xt_target *target;
|
||||
@ -1301,7 +1312,7 @@ out:
|
||||
|
||||
static int
|
||||
compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
|
||||
unsigned int *size, const char *name,
|
||||
unsigned int *size,
|
||||
struct xt_table_info *newinfo, unsigned char *base)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
@ -1334,14 +1345,9 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int translate_compat_table(const char *name,
|
||||
unsigned int valid_hooks,
|
||||
struct xt_table_info **pinfo,
|
||||
static int translate_compat_table(struct xt_table_info **pinfo,
|
||||
void **pentry0,
|
||||
unsigned int total_size,
|
||||
unsigned int number,
|
||||
unsigned int *hook_entries,
|
||||
unsigned int *underflows)
|
||||
const struct compat_arpt_replace *compatr)
|
||||
{
|
||||
unsigned int i, j;
|
||||
struct xt_table_info *newinfo, *info;
|
||||
@ -1353,8 +1359,8 @@ static int translate_compat_table(const char *name,
|
||||
|
||||
info = *pinfo;
|
||||
entry0 = *pentry0;
|
||||
size = total_size;
|
||||
info->number = number;
|
||||
size = compatr->size;
|
||||
info->number = compatr->num_entries;
|
||||
|
||||
/* Init all hooks to impossible value. */
|
||||
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
|
||||
@ -1365,40 +1371,39 @@ static int translate_compat_table(const char *name,
|
||||
duprintf("translate_compat_table: size %u\n", info->size);
|
||||
j = 0;
|
||||
xt_compat_lock(NFPROTO_ARP);
|
||||
xt_compat_init_offsets(NFPROTO_ARP, number);
|
||||
xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
|
||||
/* Walk through entries, checking offsets. */
|
||||
xt_entry_foreach(iter0, entry0, total_size) {
|
||||
xt_entry_foreach(iter0, entry0, compatr->size) {
|
||||
ret = check_compat_entry_size_and_hooks(iter0, info, &size,
|
||||
entry0,
|
||||
entry0 + total_size,
|
||||
hook_entries,
|
||||
underflows,
|
||||
name);
|
||||
entry0 + compatr->size,
|
||||
compatr->hook_entry,
|
||||
compatr->underflow);
|
||||
if (ret != 0)
|
||||
goto out_unlock;
|
||||
++j;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (j != number) {
|
||||
if (j != compatr->num_entries) {
|
||||
duprintf("translate_compat_table: %u not %u entries\n",
|
||||
j, number);
|
||||
j, compatr->num_entries);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Check hooks all assigned */
|
||||
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
|
||||
/* Only hooks which are valid */
|
||||
if (!(valid_hooks & (1 << i)))
|
||||
if (!(compatr->valid_hooks & (1 << i)))
|
||||
continue;
|
||||
if (info->hook_entry[i] == 0xFFFFFFFF) {
|
||||
duprintf("Invalid hook entry %u %u\n",
|
||||
i, hook_entries[i]);
|
||||
i, info->hook_entry[i]);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (info->underflow[i] == 0xFFFFFFFF) {
|
||||
duprintf("Invalid underflow %u %u\n",
|
||||
i, underflows[i]);
|
||||
i, info->underflow[i]);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
@ -1408,17 +1413,17 @@ static int translate_compat_table(const char *name,
|
||||
if (!newinfo)
|
||||
goto out_unlock;
|
||||
|
||||
newinfo->number = number;
|
||||
newinfo->number = compatr->num_entries;
|
||||
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
|
||||
newinfo->hook_entry[i] = info->hook_entry[i];
|
||||
newinfo->underflow[i] = info->underflow[i];
|
||||
}
|
||||
entry1 = newinfo->entries;
|
||||
pos = entry1;
|
||||
size = total_size;
|
||||
xt_entry_foreach(iter0, entry0, total_size) {
|
||||
size = compatr->size;
|
||||
xt_entry_foreach(iter0, entry0, compatr->size) {
|
||||
ret = compat_copy_entry_from_user(iter0, &pos, &size,
|
||||
name, newinfo, entry1);
|
||||
newinfo, entry1);
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
@ -1428,7 +1433,7 @@ static int translate_compat_table(const char *name,
|
||||
goto free_newinfo;
|
||||
|
||||
ret = -ELOOP;
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry1))
|
||||
if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
|
||||
goto free_newinfo;
|
||||
|
||||
i = 0;
|
||||
@ -1439,7 +1444,7 @@ static int translate_compat_table(const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
ret = check_target(iter1, name);
|
||||
ret = check_target(iter1, compatr->name);
|
||||
if (ret != 0) {
|
||||
xt_percpu_counter_free(iter1->counters.pcnt);
|
||||
break;
|
||||
@ -1481,7 +1486,7 @@ static int translate_compat_table(const char *name,
|
||||
free_newinfo:
|
||||
xt_free_table_info(newinfo);
|
||||
out:
|
||||
xt_entry_foreach(iter0, entry0, total_size) {
|
||||
xt_entry_foreach(iter0, entry0, compatr->size) {
|
||||
if (j-- == 0)
|
||||
break;
|
||||
compat_release_entry(iter0);
|
||||
@ -1493,18 +1498,6 @@ out_unlock:
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct compat_arpt_replace {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
u32 valid_hooks;
|
||||
u32 num_entries;
|
||||
u32 size;
|
||||
u32 hook_entry[NF_ARP_NUMHOOKS];
|
||||
u32 underflow[NF_ARP_NUMHOOKS];
|
||||
u32 num_counters;
|
||||
compat_uptr_t counters;
|
||||
struct compat_arpt_entry entries[0];
|
||||
};
|
||||
|
||||
static int compat_do_replace(struct net *net, void __user *user,
|
||||
unsigned int len)
|
||||
{
|
||||
@ -1537,10 +1530,7 @@ static int compat_do_replace(struct net *net, void __user *user,
|
||||
goto free_newinfo;
|
||||
}
|
||||
|
||||
ret = translate_compat_table(tmp.name, tmp.valid_hooks,
|
||||
&newinfo, &loc_cpu_entry, tmp.size,
|
||||
tmp.num_entries, tmp.hook_entry,
|
||||
tmp.underflow);
|
||||
ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
|
||||
if (ret != 0)
|
||||
goto free_newinfo;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user