On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- .../uapi/linux/netfilter_bridge/ebtables.h | 15 +++-- net/bridge/netfilter/ebtable_broute.c | 2 +- net/bridge/netfilter/ebtable_filter.c | 6 +- net/bridge/netfilter/ebtable_nat.c | 6 +- net/bridge/netfilter/ebtables.c | 64 +++++++++---------- 5 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h index 4ff328f3d339..7d4bd355e616 100644 --- a/include/uapi/linux/netfilter_bridge/ebtables.h +++ b/include/uapi/linux/netfilter_bridge/ebtables.h @@ -65,11 +65,13 @@ struct ebt_replace_kernel { /* total size of the entries */ unsigned int entries_size; /* start of the chains */ - struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; + /* Corresponds to struct ebt_entries * */ + __nf_kptr_t hook_entry[NF_BR_NUMHOOKS]; /* nr of counters userspace expects back */ unsigned int num_counters; /* where the kernel will put the old counters */ - struct ebt_counter *counters; + /* Corresponds to struct ebt_counter * */ + __nf_kptr_t counters; char *entries; };
@@ -125,7 +127,8 @@ struct ebt_entry_match { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_match *match; + /* Corresponds to struct xt_match * */ + __nf_kptr_t match; } u; /* size of data */ unsigned int match_size; @@ -138,7 +141,8 @@ struct ebt_entry_watcher { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_target *watcher; + /* Corresponds to struct xt_target * */ + __nf_kptr_t watcher; } u; /* size of data */ unsigned int watcher_size; @@ -151,7 +155,8 @@ struct ebt_entry_target { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_target *target; + /* Corresponds to struct xt_target * */ + __nf_kptr_t target; } u; /* size of data */ unsigned int target_size; diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 741360219552..39b88a2dd9d5 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -31,7 +31,7 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = 1 << NF_BR_BROUTING, .entries_size = sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_BROUTING] = &initial_chain, + [NF_BR_BROUTING] = (__nf_kptr_t) &initial_chain, }, .entries = (char *)&initial_chain, }; diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index dacd81b12e62..c0394b3bd68e 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = FILTER_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_LOCAL_IN] = &initial_chains[0], - [NF_BR_FORWARD] = &initial_chains[1], - [NF_BR_LOCAL_OUT] = &initial_chains[2], + [NF_BR_LOCAL_IN] = (__nf_kptr_t) &initial_chains[0], + [NF_BR_FORWARD] = (__nf_kptr_t) &initial_chains[1], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t) &initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 0f2a8c6118d4..da9a907e5b2d 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = NAT_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_PRE_ROUTING] = &initial_chains[0], - [NF_BR_LOCAL_OUT] = &initial_chains[1], - [NF_BR_POST_ROUTING] = &initial_chains[2], + [NF_BR_PRE_ROUTING] = (__nf_kptr_t) &initial_chains[0], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t) &initial_chains[1], + [NF_BR_POST_ROUTING] = (__nf_kptr_t) &initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3e907725529b..a06a4c8bf6f6 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -93,9 +93,9 @@ static inline int ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb, struct xt_action_param *par) { - par->target = w->u.watcher; + par->target = (struct xt_target *)w->u.watcher; par->targinfo = w->data; - w->u.watcher->target(skb, par); + ((struct xt_target *)w->u.watcher)->target(skb, par); /* watchers don't give a verdict */ return 0; } @@ -104,9 +104,9 @@ static inline int ebt_do_match(struct ebt_entry_match *m, const struct sk_buff *skb, struct xt_action_param *par) { - par->match = m->u.match; + par->match = (struct xt_match *)m->u.match; par->matchinfo = m->data; - return !m->u.match->match(skb, par); + return !((struct xt_match *)m->u.match)->match(skb, par); }
static inline int @@ -243,12 +243,12 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb,
t = ebt_get_target_c(point); /* standard target */ - if (!t->u.target->target) + if (!((struct xt_target *)t->u.target)->target) verdict = ((struct ebt_standard_target *)t)->verdict; else { - acpar.target = t->u.target; + acpar.target = (struct xt_target *)t->u.target; acpar.targinfo = t->data; - verdict = t->u.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.target)->target(skb, &acpar); } if (verdict == EBT_ACCEPT) { read_unlock_bh(&table->lock); @@ -411,7 +411,7 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, } if (IS_ERR(match)) return PTR_ERR(match); - m->u.match = match; + m->u.match = (__nf_kptr_t) match;
par->match = match; par->matchinfo = m->data; @@ -448,7 +448,7 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, return -ENOENT; }
- w->u.watcher = watcher; + w->u.watcher = (__nf_kptr_t) watcher;
par->target = watcher; par->targinfo = w->data; @@ -625,7 +625,7 @@ ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i) return 1;
par.net = net; - par.match = m->u.match; + par.match = (struct xt_match *)m->u.match; par.matchinfo = m->data; par.family = NFPROTO_BRIDGE; if (par.match->destroy != NULL) @@ -643,7 +643,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, struct net *net, unsigned int * return 1;
par.net = net; - par.target = w->u.watcher; + par.target = (struct xt_target *)w->u.watcher; par.targinfo = w->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -668,7 +668,7 @@ ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt) t = ebt_get_target(e);
par.net = net; - par.target = t->u.target; + par.target = (struct xt_target *)t->u.target; par.targinfo = t->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -759,8 +759,8 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; }
- t->u.target = target; - if (t->u.target == &ebt_standard_target) { + t->u.target = (__nf_kptr_t) target; + if (((struct xt_target *)t->u.target) == &ebt_standard_target) { if (gap < sizeof(struct ebt_standard_target)) { ret = -EFAULT; goto cleanup_watchers; @@ -771,7 +771,7 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; } } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) { - module_put(t->u.target->me); + module_put(((struct xt_target *)t->u.target)->me); ret = -EFAULT; goto cleanup_watchers; } @@ -1190,7 +1190,7 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
if (input_table == NULL || (repl = input_table->table) == NULL || repl->entries == NULL || repl->entries_size == 0 || - repl->counters != NULL || input_table->private != NULL) + ((struct xt_target *)repl->counters) != NULL || input_table->private != NULL) return -EINVAL;
/* Don't add one table to multiple lists. */ @@ -1457,18 +1457,18 @@ static inline int ebt_match_to_user(const struct ebt_entry_match *m, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)m - base), - m->u.match->name, m->data, sizeof(*m), - m->u.match->usersize, m->match_size, - m->u.match->revision); + ((struct xt_match *)m->u.match)->name, m->data, sizeof(*m), + ((struct xt_match *)m->u.match)->usersize, m->match_size, + ((struct xt_match *)m->u.match)->revision); }
static inline int ebt_watcher_to_user(const struct ebt_entry_watcher *w, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)w - base), - w->u.watcher->name, w->data, sizeof(*w), - w->u.watcher->usersize, w->watcher_size, - w->u.watcher->revision); + ((struct xt_target *)w->u.watcher)->name, w->data, sizeof(*w), + ((struct xt_target *)w->u.watcher)->usersize, w->watcher_size, + ((struct xt_target *)w->u.watcher)->revision); }
static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, @@ -1498,9 +1498,9 @@ static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, ret = EBT_WATCHER_ITERATE(e, ebt_watcher_to_user, base, ubase); if (ret != 0) return ret; - ret = ebt_obj_to_user(hlp, t->u.target->name, t->data, sizeof(*t), - t->u.target->usersize, t->target_size, - t->u.target->revision); + ret = ebt_obj_to_user(hlp, ((struct xt_target *)t->u.target)->name, t->data, sizeof(*t), + ((struct xt_target *)t->u.target)->usersize, t->target_size, + ((struct xt_target *)t->u.target)->revision); if (ret != 0) return ret;
@@ -1556,7 +1556,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user, entries_size = t->table->entries_size; nentries = t->table->nentries; entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp))) @@ -1641,7 +1641,7 @@ static int compat_match_to_user(struct ebt_entry_match *m, #endif unsigned int *size) { - const struct xt_match *match = m->u.match; + const struct xt_match *match = (struct xt_match *)m->u.match; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = ebt_compat_match_offset(match, m->match_size); compat_uint_t msize = m->match_size - off; @@ -1677,7 +1677,7 @@ static int compat_target_to_user(struct ebt_entry_target *t, #endif unsigned int *size) { - const struct xt_target *target = t->u.target; + const struct xt_target *target = (struct xt_target *)t->u.target; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = xt_compat_target_offset(target); compat_uint_t tsize = t->target_size - off; @@ -1780,14 +1780,14 @@ static int compat_copy_entry_to_user(struct ebt_entry *e,
static int compat_calc_match(struct ebt_entry_match *m, int *off) { - *off += ebt_compat_match_offset(m->u.match, m->match_size); + *off += ebt_compat_match_offset((struct xt_match *)m->u.match, m->match_size); *off += ebt_compat_entry_padsize(); return 0; }
static int compat_calc_watcher(struct ebt_entry_watcher *w, int *off) { - *off += xt_compat_target_offset(w->u.watcher); + *off += xt_compat_target_offset((struct xt_target *)w->u.watcher); *off += ebt_compat_entry_padsize(); return 0; } @@ -1812,7 +1812,7 @@ static int compat_calc_entry(const struct ebt_entry *e,
t = ebt_get_target_c(e);
- off += xt_compat_target_offset(t->u.target); + off += xt_compat_target_offset((struct xt_target *)t->u.target); off += ebt_compat_entry_padsize();
newinfo->entries_size -= off; @@ -1882,7 +1882,7 @@ static int compat_copy_everything_to_user(struct ebt_table *t, tinfo.entries_size = t->table->entries_size; tinfo.nentries = t->table->nentries; tinfo.entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp)))