[NETFILTER]: ip_tables: fix compat types
Use compat types and compat iterators when dealing with compat entries for clarity. This doesn't actually make a difference for ip_tables, but is needed for ip6_tables and arp_tables. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
30c08c41be
Коммит
73cd598df4
|
@ -236,11 +236,6 @@ ipt_get_target(struct ipt_entry *e)
|
||||||
#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
|
#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
|
||||||
XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
|
XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
|
||||||
|
|
||||||
/* fn returns 0 to continue iteration */
|
|
||||||
#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
|
|
||||||
XT_ENTRY_ITERATE_CONTINUE(struct ipt_entry, entries, size, n, fn, \
|
|
||||||
## args)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main firewall chains definitions and global var's definitions.
|
* Main firewall chains definitions and global var's definitions.
|
||||||
*/
|
*/
|
||||||
|
@ -316,8 +311,28 @@ struct compat_ipt_entry
|
||||||
unsigned char elems[0];
|
unsigned char elems[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Helper functions */
|
||||||
|
static inline struct ipt_entry_target *
|
||||||
|
compat_ipt_get_target(struct compat_ipt_entry *e)
|
||||||
|
{
|
||||||
|
return (void *)e + e->target_offset;
|
||||||
|
}
|
||||||
|
|
||||||
#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)
|
#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)
|
||||||
|
|
||||||
|
/* fn returns 0 to continue iteration */
|
||||||
|
#define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \
|
||||||
|
XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args)
|
||||||
|
|
||||||
|
/* fn returns 0 to continue iteration */
|
||||||
|
#define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \
|
||||||
|
XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args)
|
||||||
|
|
||||||
|
/* fn returns 0 to continue iteration */
|
||||||
|
#define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
|
||||||
|
XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \
|
||||||
|
fn, ## args)
|
||||||
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
#endif /*__KERNEL__*/
|
#endif /*__KERNEL__*/
|
||||||
#endif /* _IPTABLES_H */
|
#endif /* _IPTABLES_H */
|
||||||
|
|
|
@ -1559,7 +1559,7 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
compat_release_entry(struct ipt_entry *e, unsigned int *i)
|
compat_release_entry(struct compat_ipt_entry *e, unsigned int *i)
|
||||||
{
|
{
|
||||||
struct ipt_entry_target *t;
|
struct ipt_entry_target *t;
|
||||||
|
|
||||||
|
@ -1567,14 +1567,14 @@ compat_release_entry(struct ipt_entry *e, unsigned int *i)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Cleanup all matches */
|
/* Cleanup all matches */
|
||||||
IPT_MATCH_ITERATE(e, compat_release_match, NULL);
|
COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL);
|
||||||
t = ipt_get_target(e);
|
t = compat_ipt_get_target(e);
|
||||||
module_put(t->u.kernel.target->me);
|
module_put(t->u.kernel.target->me);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
check_compat_entry_size_and_hooks(struct ipt_entry *e,
|
check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
|
||||||
struct xt_table_info *newinfo,
|
struct xt_table_info *newinfo,
|
||||||
unsigned int *size,
|
unsigned int *size,
|
||||||
unsigned char *base,
|
unsigned char *base,
|
||||||
|
@ -1603,19 +1603,20 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = check_entry(e, name);
|
/* For purposes of check_entry casting the compat entry is fine */
|
||||||
|
ret = check_entry((struct ipt_entry *)e, name);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
|
off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
|
||||||
entry_offset = (void *)e - (void *)base;
|
entry_offset = (void *)e - (void *)base;
|
||||||
j = 0;
|
j = 0;
|
||||||
ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
|
ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name,
|
||||||
e->comefrom, &off, &j);
|
&e->ip, e->comefrom, &off, &j);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto release_matches;
|
goto release_matches;
|
||||||
|
|
||||||
t = ipt_get_target(e);
|
t = compat_ipt_get_target(e);
|
||||||
target = try_then_request_module(xt_find_target(AF_INET,
|
target = try_then_request_module(xt_find_target(AF_INET,
|
||||||
t->u.user.name,
|
t->u.user.name,
|
||||||
t->u.user.revision),
|
t->u.user.revision),
|
||||||
|
@ -1643,7 +1644,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear counters and comefrom */
|
/* Clear counters and comefrom */
|
||||||
e->counters = ((struct ipt_counters) { 0, 0 });
|
memset(&e->counters, 0, sizeof(e->counters));
|
||||||
e->comefrom = 0;
|
e->comefrom = 0;
|
||||||
|
|
||||||
(*i)++;
|
(*i)++;
|
||||||
|
@ -1657,7 +1658,7 @@ release_matches:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
|
compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
|
||||||
unsigned int *size, const char *name,
|
unsigned int *size, const char *name,
|
||||||
struct xt_table_info *newinfo, unsigned char *base)
|
struct xt_table_info *newinfo, unsigned char *base)
|
||||||
{
|
{
|
||||||
|
@ -1671,15 +1672,17 @@ compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
|
||||||
origsize = *size;
|
origsize = *size;
|
||||||
de = (struct ipt_entry *)*dstptr;
|
de = (struct ipt_entry *)*dstptr;
|
||||||
memcpy(de, e, sizeof(struct ipt_entry));
|
memcpy(de, e, sizeof(struct ipt_entry));
|
||||||
|
memcpy(&de->counters, &e->counters, sizeof(e->counters));
|
||||||
|
|
||||||
*dstptr += sizeof(struct compat_ipt_entry);
|
*dstptr += sizeof(struct ipt_entry);
|
||||||
*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
|
*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
|
||||||
|
|
||||||
ret = IPT_MATCH_ITERATE(e, xt_compat_match_from_user, dstptr, size);
|
ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user,
|
||||||
|
dstptr, size);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
de->target_offset = e->target_offset - (origsize - *size);
|
de->target_offset = e->target_offset - (origsize - *size);
|
||||||
t = ipt_get_target(e);
|
t = compat_ipt_get_target(e);
|
||||||
target = t->u.kernel.target;
|
target = t->u.kernel.target;
|
||||||
xt_compat_target_from_user(t, dstptr, size);
|
xt_compat_target_from_user(t, dstptr, size);
|
||||||
|
|
||||||
|
@ -1746,11 +1749,11 @@ translate_compat_table(const char *name,
|
||||||
j = 0;
|
j = 0;
|
||||||
xt_compat_lock(AF_INET);
|
xt_compat_lock(AF_INET);
|
||||||
/* Walk through entries, checking offsets. */
|
/* Walk through entries, checking offsets. */
|
||||||
ret = IPT_ENTRY_ITERATE(entry0, total_size,
|
ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
|
||||||
check_compat_entry_size_and_hooks,
|
check_compat_entry_size_and_hooks,
|
||||||
info, &size, entry0,
|
info, &size, entry0,
|
||||||
entry0 + total_size,
|
entry0 + total_size,
|
||||||
hook_entries, underflows, &j, name);
|
hook_entries, underflows, &j, name);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
@ -1791,9 +1794,9 @@ translate_compat_table(const char *name,
|
||||||
entry1 = newinfo->entries[raw_smp_processor_id()];
|
entry1 = newinfo->entries[raw_smp_processor_id()];
|
||||||
pos = entry1;
|
pos = entry1;
|
||||||
size = total_size;
|
size = total_size;
|
||||||
ret = IPT_ENTRY_ITERATE(entry0, total_size,
|
ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
|
||||||
compat_copy_entry_from_user, &pos, &size,
|
compat_copy_entry_from_user, &pos, &size,
|
||||||
name, newinfo, entry1);
|
name, newinfo, entry1);
|
||||||
compat_flush_offsets();
|
compat_flush_offsets();
|
||||||
xt_compat_unlock(AF_INET);
|
xt_compat_unlock(AF_INET);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1808,8 +1811,8 @@ translate_compat_table(const char *name,
|
||||||
name, &i);
|
name, &i);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
j -= i;
|
j -= i;
|
||||||
IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
|
COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
|
||||||
compat_release_entry, &j);
|
compat_release_entry, &j);
|
||||||
IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
|
IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
|
||||||
xt_free_table_info(newinfo);
|
xt_free_table_info(newinfo);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1828,7 +1831,7 @@ translate_compat_table(const char *name,
|
||||||
free_newinfo:
|
free_newinfo:
|
||||||
xt_free_table_info(newinfo);
|
xt_free_table_info(newinfo);
|
||||||
out:
|
out:
|
||||||
IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
|
COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
|
||||||
return ret;
|
return ret;
|
||||||
out_unlock:
|
out_unlock:
|
||||||
compat_flush_offsets();
|
compat_flush_offsets();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче