Many of the uapi structs in the netfilter subsystem contain kernel pointers which cause alignment issues when the kernel parses netlink messages. Change these pointers to use unsigned longs, and cast to a pointer when used inside the kernel.
For more information on the necessity of these patches, see discussion in this thread:
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/...
Joshua Lant (16): x_tables.h: remove kernel pointer from uapi xt_entry_match struct x_tables.h: remove kernel pointer from uapi xt_entry_target struct xt_CT: remove pointer from uapi struct xt_IDLETIMER: remove pointer from uapi struct xt_RATEEST: remove pointer from uapi struct xt_TEE: remove pointer from uapi struct xt_bpf: remove pointer from uapi struct xt_connlimit: remove pointer from uapi struct xt_hashlimit: remove pointer from uapi struct xt_limit: remove pointer from uapi struct xt_nfacct: remove pointer from uapi struct xt_quota: remove pointer from uapi struct xt_rateest: remove pointer from uapi struct xt_statistic: remove pointer from uapi struct ebtables: remove pointer from uapi struct ipt_CLUSTERIP: remove pointer from uapi struct
include/uapi/linux/netfilter/x_tables.h | 4 +- include/uapi/linux/netfilter/xt_CT.h | 4 +- include/uapi/linux/netfilter/xt_IDLETIMER.h | 6 +- include/uapi/linux/netfilter/xt_RATEEST.h | 3 +- include/uapi/linux/netfilter/xt_TEE.h | 3 +- include/uapi/linux/netfilter/xt_bpf.h | 6 +- include/uapi/linux/netfilter/xt_connlimit.h | 3 +- include/uapi/linux/netfilter/xt_hashlimit.h | 17 ++- include/uapi/linux/netfilter/xt_limit.h | 3 +- include/uapi/linux/netfilter/xt_nfacct.h | 6 +- include/uapi/linux/netfilter/xt_quota.h | 3 +- include/uapi/linux/netfilter/xt_rateest.h | 5 +- include/uapi/linux/netfilter/xt_statistic.h | 3 +- .../uapi/linux/netfilter_bridge/ebtables.h | 15 +- .../uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 3 +- 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 ++++----- net/ipv4/netfilter/arp_tables.c | 22 +-- net/ipv4/netfilter/ip_tables.c | 44 +++--- net/ipv6/netfilter/ip6_tables.c | 44 +++--- net/netfilter/x_tables.c | 20 +-- net/netfilter/xt_CT.c | 10 +- net/netfilter/xt_IDLETIMER.c | 132 +++++++++--------- net/netfilter/xt_RATEEST.c | 12 +- net/netfilter/xt_TCPMSS.c | 2 +- net/netfilter/xt_TEE.c | 12 +- net/netfilter/xt_bpf.c | 18 +-- net/netfilter/xt_connlimit.c | 8 +- net/netfilter/xt_hashlimit.c | 24 ++-- net/netfilter/xt_limit.c | 6 +- net/netfilter/xt_nfacct.c | 8 +- net/netfilter/xt_quota.c | 12 +- net/netfilter/xt_rateest.c | 12 +- net/netfilter/xt_statistic.c | 12 +- 36 files changed, 294 insertions(+), 266 deletions(-)
Kernel pointer in uapi struct causes alignment issues moving between user-space and kernel-space. Change this to an unsigned int and make kernel accesses explicitly cast back to pointer.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/x_tables.h | 2 +- net/ipv4/netfilter/ip_tables.c | 18 +++++++++--------- net/ipv6/netfilter/ip6_tables.c | 18 +++++++++--------- net/netfilter/x_tables.c | 16 ++++++++-------- net/netfilter/xt_TCPMSS.c | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h index 796af83a963a..0122c4624886 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -21,7 +21,7 @@ struct xt_entry_match { __u16 match_size;
/* Used inside the kernel */ - struct xt_match *match; + unsigned long match; } kernel;
/* Total length */ diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a54c54d4ba9c..236c2a7abad7 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -288,7 +288,7 @@ ipt_do_table(void *priv, }
xt_ematch_foreach(ematch, e) { - acpar.match = ematch->u.kernel.match; + acpar.match = (const struct xt_match *) ematch->u.kernel.match; acpar.matchinfo = ematch->data; if (!acpar.match->match(skb, &acpar)) goto no_match; @@ -452,7 +452,7 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) struct xt_mtdtor_param par;
par.net = net; - par.match = m->u.kernel.match; + par.match = (const struct xt_match *) m->u.kernel.match; par.matchinfo = m->data; par.family = NFPROTO_IPV4; if (par.match->destroy != NULL) @@ -465,7 +465,7 @@ check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ipt_ip *ip = par->entryinfo;
- par->match = m->u.kernel.match; + par->match = (const struct xt_match *) m->u.kernel.match; par->matchinfo = m->data;
return xt_check_match(par, m->u.match_size - sizeof(*m), @@ -482,7 +482,7 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) m->u.user.revision); if (IS_ERR(match)) return PTR_ERR(match); - m->u.kernel.match = match; + m->u.kernel.match = (unsigned long) match;
ret = check_match(m, par); if (ret) @@ -490,7 +490,7 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
return 0; err: - module_put(m->u.kernel.match->me); + module_put(((struct xt_match *)(m->u.kernel.match))->me); return ret; }
@@ -898,7 +898,7 @@ static int compat_calc_entry(const struct ipt_entry *e, off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); entry_offset = (void *)e - base; xt_ematch_foreach(ematch, e) - off += xt_compat_match_offset(ematch->u.kernel.match); + off += xt_compat_match_offset((struct xt_match *) ematch->u.kernel.match); t = ipt_get_target_c(e); off += xt_compat_target_offset(t->u.kernel.target); newinfo->size -= off; @@ -1265,7 +1265,7 @@ compat_find_calc_match(struct xt_entry_match *m, if (IS_ERR(match)) return PTR_ERR(match);
- m->u.kernel.match = match; + m->u.kernel.match = (unsigned long) match; *size += xt_compat_match_offset(match); return 0; } @@ -1277,7 +1277,7 @@ static void compat_release_entry(struct compat_ipt_entry *e)
/* Cleanup all matches */ xt_ematch_foreach(ematch, e) - module_put(ematch->u.kernel.match->me); + module_put(((struct xt_match *)ematch->u.kernel.match)->me); t = compat_ipt_get_target(e); module_put(t->u.kernel.target->me); } @@ -1346,7 +1346,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, xt_ematch_foreach(ematch, e) { if (j-- == 0) break; - module_put(ematch->u.kernel.match->me); + module_put(((struct xt_match *)ematch->u.kernel.match)->me); } return ret; } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 9bb1fa0f497c..120018ed7cd8 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -311,7 +311,7 @@ ip6t_do_table(void *priv, struct sk_buff *skb, }
xt_ematch_foreach(ematch, e) { - acpar.match = ematch->u.kernel.match; + acpar.match = (const struct xt_match *) ematch->u.kernel.match; acpar.matchinfo = ematch->data; if (!acpar.match->match(skb, &acpar)) goto no_match; @@ -470,7 +470,7 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) struct xt_mtdtor_param par;
par.net = net; - par.match = m->u.kernel.match; + par.match = (const struct xt_match *) m->u.kernel.match; par.matchinfo = m->data; par.family = NFPROTO_IPV6; if (par.match->destroy != NULL) @@ -482,7 +482,7 @@ static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ip6t_ip6 *ipv6 = par->entryinfo;
- par->match = m->u.kernel.match; + par->match = (const struct xt_match *) m->u.kernel.match; par->matchinfo = m->data;
return xt_check_match(par, m->u.match_size - sizeof(*m), @@ -500,7 +500,7 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) if (IS_ERR(match)) return PTR_ERR(match);
- m->u.kernel.match = match; + m->u.kernel.match = (unsigned long) match;
ret = check_match(m, par); if (ret) @@ -508,7 +508,7 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
return 0; err: - module_put(m->u.kernel.match->me); + module_put(((struct xt_match *)(m->u.kernel.match))->me); return ret; }
@@ -914,7 +914,7 @@ static int compat_calc_entry(const struct ip6t_entry *e, off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); entry_offset = (void *)e - base; xt_ematch_foreach(ematch, e) - off += xt_compat_match_offset(ematch->u.kernel.match); + off += xt_compat_match_offset((struct xt_match *) ematch->u.kernel.match); t = ip6t_get_target_c(e); off += xt_compat_target_offset(t->u.kernel.target); newinfo->size -= off; @@ -1281,7 +1281,7 @@ compat_find_calc_match(struct xt_entry_match *m, if (IS_ERR(match)) return PTR_ERR(match);
- m->u.kernel.match = match; + m->u.kernel.match = (unsigned long) match; *size += xt_compat_match_offset(match); return 0; } @@ -1293,7 +1293,7 @@ static void compat_release_entry(struct compat_ip6t_entry *e)
/* Cleanup all matches */ xt_ematch_foreach(ematch, e) - module_put(ematch->u.kernel.match->me); + module_put(((struct xt_match *)ematch->u.kernel.match)->me); t = compat_ip6t_get_target(e); module_put(t->u.kernel.target->me); } @@ -1362,7 +1362,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, xt_ematch_foreach(ematch, e) { if (j-- == 0) break; - module_put(ematch->u.kernel.match->me); + module_put(((struct xt_match *)ematch->u.kernel.match)->me); } return ret; } diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index caf838d56f4d..2e347789593a 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -306,8 +306,8 @@ static int xt_obj_to_user(u16 __user *psize, u16 size,
#define XT_OBJ_TO_USER(U, K, TYPE, C_SIZE) \ xt_obj_to_user(&U->u.TYPE##_size, C_SIZE ? : K->u.TYPE##_size, \ - U->u.user.name, K->u.kernel.TYPE->name, \ - &U->u.user.revision, K->u.kernel.TYPE->revision) + U->u.user.name, ((struct xt_##TYPE *)(K->u.kernel.TYPE))->name, \ + &U->u.user.revision, ((struct xt_##TYPE *)(K->u.kernel.TYPE))->revision)
int xt_data_to_user(void __user *dst, const void *src, int usersize, int size, int aligned_size) @@ -325,9 +325,9 @@ EXPORT_SYMBOL_GPL(xt_data_to_user);
#define XT_DATA_TO_USER(U, K, TYPE) \ xt_data_to_user(U->data, K->data, \ - K->u.kernel.TYPE->usersize, \ - K->u.kernel.TYPE->TYPE##size, \ - XT_ALIGN(K->u.kernel.TYPE->TYPE##size)) + ((struct xt_##TYPE *)(K->u.kernel.TYPE))->usersize, \ + ((struct xt_##TYPE *)(K->u.kernel.TYPE))->TYPE##size, \ + XT_ALIGN(((struct xt_##TYPE *)(K->u.kernel.TYPE))->TYPE##size))
int xt_match_to_user(const struct xt_entry_match *m, struct xt_entry_match __user *u) @@ -751,7 +751,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_offset); void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, unsigned int *size) { - const struct xt_match *match = m->u.kernel.match; + const struct xt_match *match = (struct xt_match *) m->u.kernel.match; struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m; int off = xt_compat_match_offset(match); u_int16_t msize = cm->u.user.match_size; @@ -777,7 +777,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
#define COMPAT_XT_DATA_TO_USER(U, K, TYPE, C_SIZE) \ xt_data_to_user(U->data, K->data, \ - K->u.kernel.TYPE->usersize, \ + ((struct xt_##TYPE *)(K->u.kernel.TYPE))->usersize, \ C_SIZE, \ COMPAT_XT_ALIGN(C_SIZE))
@@ -788,7 +788,7 @@ int xt_compat_match_to_user(const struct xt_entry_match *m, void __user **dstptr, unsigned int *size) #endif { - const struct xt_match *match = m->u.kernel.match; + const struct xt_match *match = (struct xt_match *) m->u.kernel.match; struct compat_xt_entry_match __user *cm = *dstptr; int off = xt_compat_match_offset(match); u_int16_t msize = m->u.user.match_size - off; diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 116a885adb3c..81841f55e6e8 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -252,7 +252,7 @@ static inline bool find_syn_match(const struct xt_entry_match *m) { const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data;
- if (strcmp(m->u.kernel.match->name, "tcp") == 0 && + if (strcmp(((struct xt_match *)(m->u.kernel.match))->name, "tcp") == 0 && tcpinfo->flg_cmp & TCPHDR_SYN && !(tcpinfo->invflags & XT_TCP_INV_FLAGS)) return true;
On 12/08/2024 16:11, Joshua Lant wrote:
Kernel pointer in uapi struct causes alignment issues moving between user-space and kernel-space. Change this to an unsigned int and make
Nit: s/unsigned int/unsigned long/
kernel accesses explicitly cast back to pointer.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter/x_tables.h | 2 +- net/ipv4/netfilter/ip_tables.c | 18 +++++++++--------- net/ipv6/netfilter/ip6_tables.c | 18 +++++++++--------- net/netfilter/x_tables.c | 16 ++++++++-------- net/netfilter/xt_TCPMSS.c | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h index 796af83a963a..0122c4624886 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -21,7 +21,7 @@ struct xt_entry_match { __u16 match_size; /* Used inside the kernel */
struct xt_match *match;
} kernel;unsigned long match;
/* Total length */ diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a54c54d4ba9c..236c2a7abad7 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -288,7 +288,7 @@ ipt_do_table(void *priv, } xt_ematch_foreach(ematch, e) {
acpar.match = ematch->u.kernel.match;
acpar.match = (const struct xt_match *) ematch->u.kernel.match;
Nit: preferably no space between the cast and the variable.
[...]
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index caf838d56f4d..2e347789593a 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -306,8 +306,8 @@ static int xt_obj_to_user(u16 __user *psize, u16 size, #define XT_OBJ_TO_USER(U, K, TYPE, C_SIZE) \ xt_obj_to_user(&U->u.TYPE##_size, C_SIZE ? : K->u.TYPE##_size, \
U->u.user.name, K->u.kernel.TYPE->name, \
&U->u.user.revision, K->u.kernel.TYPE->revision)
U->u.user.name, ((struct xt_##TYPE *)(K->u.kernel.TYPE))->name, \
&U->u.user.revision, ((struct xt_##TYPE *)(K->u.kernel.TYPE))->revision)
Nit: you can omit the parentheses around the expression to cast, i.e. K->u.kernel.TYPE.
Kevin
[...]
Kernel pointer in uapi struct causes alignment issues moving between user-space and kernel-space. Change this to an unsigned int and make kernel accesses explicitly cast back to pointer.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/x_tables.h | 2 +- net/ipv4/netfilter/arp_tables.c | 22 ++++++++++----------- net/ipv4/netfilter/ip_tables.c | 26 ++++++++++++------------- net/ipv6/netfilter/ip6_tables.c | 26 ++++++++++++------------- net/netfilter/x_tables.c | 4 ++-- 5 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h index 0122c4624886..8866b87ccc82 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -44,7 +44,7 @@ struct xt_entry_target { __u16 target_size;
/* Used inside the kernel */ - struct xt_target *target; + unsigned long target; } kernel;
/* Total length */ diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index fb6eb846c381..b222396221ec 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -233,7 +233,7 @@ unsigned int arpt_do_table(void *priv, t = arpt_get_target_c(e);
/* Standard target? */ - if (!t->u.kernel.target->target) { + if (!((struct xt_target *)t->u.kernel.target)->target) { int v;
v = ((struct xt_standard_target *)t)->verdict; @@ -265,9 +265,9 @@ unsigned int arpt_do_table(void *priv, continue; }
- acpar.target = t->u.kernel.target; + acpar.target = (struct xt_target *) t->u.kernel.target; acpar.targinfo = t->data; - verdict = t->u.kernel.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.kernel.target)->target(skb, &acpar);
if (verdict == XT_CONTINUE) { /* Target might have changed stuff. */ @@ -392,7 +392,7 @@ static int check_target(struct arpt_entry *e, struct net *net, const char *name) .net = net, .table = name, .entryinfo = e, - .target = t->u.kernel.target, + .target = (struct xt_target *) t->u.kernel.target, .targinfo = t->data, .hook_mask = e->comefrom, .family = NFPROTO_ARP, @@ -420,14 +420,14 @@ find_check_entry(struct arpt_entry *e, struct net *net, const char *name, ret = PTR_ERR(target); goto out; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
ret = check_target(e, net, name); if (ret) goto err; return 0; err: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); out: xt_percpu_counter_free(&e->counters);
@@ -504,7 +504,7 @@ static void cleanup_entry(struct arpt_entry *e, struct net *net)
t = arpt_get_target(e); par.net = net; - par.target = t->u.kernel.target; + par.target = (struct xt_target *) t->u.kernel.target; par.targinfo = t->data; par.family = NFPROTO_ARP; if (par.target->destroy != NULL) @@ -745,7 +745,7 @@ static int compat_calc_entry(const struct arpt_entry *e, entry_offset = (void *)e - base;
t = arpt_get_target_c(e); - off += xt_compat_target_offset(t->u.kernel.target); + off += xt_compat_target_offset((struct xt_target *)t->u.kernel.target); newinfo->size -= off; ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); if (ret) @@ -1063,7 +1063,7 @@ static inline void compat_release_entry(struct compat_arpt_entry *e) struct xt_entry_target *t;
t = compat_arpt_get_target(e); - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); }
static int @@ -1105,7 +1105,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, ret = PTR_ERR(target); goto out; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
off += xt_compat_target_offset(target); *size += off; @@ -1116,7 +1116,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, return 0;
release_target: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); out: return ret; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 236c2a7abad7..f69c5d47221f 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -159,7 +159,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, { const struct xt_standard_target *t = (void *)ipt_get_target_c(s);
- if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { + if (strcmp(((struct xt_target *)t->target.u.kernel.target)->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -167,7 +167,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, (*rulenum)++;
if (unconditional(s) && - strcmp(t->target.u.kernel.target->name, + strcmp(((struct xt_target *)t->target.u.kernel.target)->name, XT_STANDARD_TARGET) == 0 && t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ @@ -307,7 +307,7 @@ ipt_do_table(void *priv, state->out, table->name, private, e); #endif /* Standard target? */ - if (!t->u.kernel.target->target) { + if (!((struct xt_target *)t->u.kernel.target)->target) { int v;
v = ((struct xt_standard_target *)t)->verdict; @@ -339,10 +339,10 @@ ipt_do_table(void *priv, continue; }
- acpar.target = t->u.kernel.target; + acpar.target = (struct xt_target *) t->u.kernel.target; acpar.targinfo = t->data;
- verdict = t->u.kernel.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.kernel.target)->target(skb, &acpar); if (verdict == XT_CONTINUE) { /* Target might have changed stuff. */ ip = ip_hdr(skb); @@ -501,7 +501,7 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name) .net = net, .table = name, .entryinfo = e, - .target = t->u.kernel.target, + .target = (struct xt_target *) t->u.kernel.target, .targinfo = t->data, .hook_mask = e->comefrom, .family = NFPROTO_IPV4, @@ -547,7 +547,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, ret = PTR_ERR(target); goto cleanup_matches; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
ret = check_target(e, net, name); if (ret) @@ -555,7 +555,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
return 0; err: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); cleanup_matches: xt_ematch_foreach(ematch, e) { if (j-- == 0) @@ -645,7 +645,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net) t = ipt_get_target(e);
par.net = net; - par.target = t->u.kernel.target; + par.target = (struct xt_target *) t->u.kernel.target; par.targinfo = t->data; par.family = NFPROTO_IPV4; if (par.target->destroy != NULL) @@ -900,7 +900,7 @@ static int compat_calc_entry(const struct ipt_entry *e, xt_ematch_foreach(ematch, e) off += xt_compat_match_offset((struct xt_match *) ematch->u.kernel.match); t = ipt_get_target_c(e); - off += xt_compat_target_offset(t->u.kernel.target); + off += xt_compat_target_offset((struct xt_target *) t->u.kernel.target); newinfo->size -= off; ret = xt_compat_add_offset(AF_INET, entry_offset, off); if (ret) @@ -1279,7 +1279,7 @@ static void compat_release_entry(struct compat_ipt_entry *e) xt_ematch_foreach(ematch, e) module_put(((struct xt_match *)ematch->u.kernel.match)->me); t = compat_ipt_get_target(e); - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); }
static int @@ -1330,7 +1330,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, ret = PTR_ERR(target); goto release_matches; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
off += xt_compat_target_offset(target); *size += off; @@ -1341,7 +1341,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, return 0;
out: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); release_matches: xt_ematch_foreach(ematch, e) { if (j-- == 0) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 120018ed7cd8..7d70576f499d 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -184,7 +184,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, { const struct xt_standard_target *t = (void *)ip6t_get_target_c(s);
- if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { + if (strcmp(((struct xt_target *)t->target.u.kernel.target)->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -192,7 +192,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, (*rulenum)++;
if (unconditional(s) && - strcmp(t->target.u.kernel.target->name, + strcmp(((struct xt_target *)t->target.u.kernel.target)->name, XT_STANDARD_TARGET) == 0 && t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ @@ -330,7 +330,7 @@ ip6t_do_table(void *priv, struct sk_buff *skb, state->out, table->name, private, e); #endif /* Standard target? */ - if (!t->u.kernel.target->target) { + if (!((struct xt_target *)t->u.kernel.target)->target) { int v;
v = ((struct xt_standard_target *)t)->verdict; @@ -360,10 +360,10 @@ ip6t_do_table(void *priv, struct sk_buff *skb, continue; }
- acpar.target = t->u.kernel.target; + acpar.target = (struct xt_target *) t->u.kernel.target; acpar.targinfo = t->data;
- verdict = t->u.kernel.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.kernel.target)->target(skb, &acpar); if (verdict == XT_CONTINUE) e = ip6t_next_entry(e); else @@ -519,7 +519,7 @@ static int check_target(struct ip6t_entry *e, struct net *net, const char *name) .net = net, .table = name, .entryinfo = e, - .target = t->u.kernel.target, + .target = (struct xt_target *) t->u.kernel.target, .targinfo = t->data, .hook_mask = e->comefrom, .family = NFPROTO_IPV6, @@ -566,14 +566,14 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, ret = PTR_ERR(target); goto cleanup_matches; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
ret = check_target(e, net, name); if (ret) goto err; return 0; err: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); cleanup_matches: xt_ematch_foreach(ematch, e) { if (j-- == 0) @@ -662,7 +662,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net) t = ip6t_get_target(e);
par.net = net; - par.target = t->u.kernel.target; + par.target = (struct xt_target *) t->u.kernel.target; par.targinfo = t->data; par.family = NFPROTO_IPV6; if (par.target->destroy != NULL) @@ -916,7 +916,7 @@ static int compat_calc_entry(const struct ip6t_entry *e, xt_ematch_foreach(ematch, e) off += xt_compat_match_offset((struct xt_match *) ematch->u.kernel.match); t = ip6t_get_target_c(e); - off += xt_compat_target_offset(t->u.kernel.target); + off += xt_compat_target_offset((struct xt_target *) t->u.kernel.target); newinfo->size -= off; ret = xt_compat_add_offset(AF_INET6, entry_offset, off); if (ret) @@ -1295,7 +1295,7 @@ static void compat_release_entry(struct compat_ip6t_entry *e) xt_ematch_foreach(ematch, e) module_put(((struct xt_match *)ematch->u.kernel.match)->me); t = compat_ip6t_get_target(e); - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); }
static int @@ -1346,7 +1346,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, ret = PTR_ERR(target); goto release_matches; } - t->u.kernel.target = target; + t->u.kernel.target = (unsigned long) target;
off += xt_compat_target_offset(target); *size += off; @@ -1357,7 +1357,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, return 0;
out: - module_put(t->u.kernel.target->me); + module_put(((struct xt_target *)t->u.kernel.target)->me); release_matches: xt_ematch_foreach(ematch, e) { if (j-- == 0) diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 2e347789593a..66168d74ebac 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1135,7 +1135,7 @@ EXPORT_SYMBOL_GPL(xt_compat_target_offset); void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, unsigned int *size) { - const struct xt_target *target = t->u.kernel.target; + const struct xt_target *target = (struct xt_target *) t->u.kernel.target; struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t; int off = xt_compat_target_offset(target); u_int16_t tsize = ct->u.user.target_size; @@ -1166,7 +1166,7 @@ int xt_compat_target_to_user(const struct xt_entry_target *t, void __user **dstptr, unsigned int *size) #endif { - const struct xt_target *target = t->u.kernel.target; + const struct xt_target *target = (struct xt_target *) t->u.kernel.target; struct compat_xt_entry_target __user *ct = *dstptr; int off = xt_compat_target_offset(target); u_int16_t tsize = t->u.user.target_size - off;
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_CT.h | 4 ++-- net/netfilter/xt_CT.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_CT.h b/include/uapi/linux/netfilter/xt_CT.h index 868fa08e1fbb..156b4d9d5e17 100644 --- a/include/uapi/linux/netfilter/xt_CT.h +++ b/include/uapi/linux/netfilter/xt_CT.h @@ -24,7 +24,7 @@ struct xt_ct_target_info { char helper[16];
/* Used internally by the kernel */ - struct nf_conn *ct __attribute__((aligned(8))); + unsigned long ct __attribute__((aligned(8))); };
struct xt_ct_target_info_v1 { @@ -36,7 +36,7 @@ struct xt_ct_target_info_v1 { char timeout[32];
/* Used internally by the kernel */ - struct nf_conn *ct __attribute__((aligned(8))); + unsigned long ct __attribute__((aligned(8))); };
#endif /* _XT_CT_H */ diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 2be2f7a7b60f..adef10a88106 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -37,7 +37,7 @@ static unsigned int xt_ct_target_v0(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info *info = par->targinfo; - struct nf_conn *ct = info->ct; + struct nf_conn *ct = (struct nf_conn *) info->ct;
return xt_ct_target(skb, ct); } @@ -46,7 +46,7 @@ static unsigned int xt_ct_target_v1(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_ct_target_info_v1 *info = par->targinfo; - struct nf_conn *ct = info->ct; + struct nf_conn *ct = (struct nf_conn *) info->ct;
return xt_ct_target(skb, ct); } @@ -217,7 +217,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, } __set_bit(IPS_CONFIRMED_BIT, &ct->status); out: - info->ct = ct; + info->ct = (unsigned long) ct; return 0;
err4: @@ -279,7 +279,7 @@ static int xt_ct_tg_check_v2(const struct xt_tgchk_param *par) static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, struct xt_ct_target_info_v1 *info) { - struct nf_conn *ct = info->ct; + struct nf_conn *ct = (struct nf_conn *) info->ct; struct nf_conn_help *help;
if (ct) { @@ -289,7 +289,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, nf_ct_netns_put(par->net, par->family);
nf_ct_destroy_timeout(ct); - nf_ct_put(info->ct); + nf_ct_put((struct nf_conn *) info->ct); } }
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_IDLETIMER.h | 6 +- net/netfilter/xt_IDLETIMER.c | 132 ++++++++++---------- 2 files changed, 70 insertions(+), 68 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h index 7bfb31a66fc9..eef4aa6c6649 100644 --- a/include/uapi/linux/netfilter/xt_IDLETIMER.h +++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h @@ -25,7 +25,8 @@ struct idletimer_tg_info { char label[MAX_IDLETIMER_LABEL_SIZE];
/* for kernel module internal use only */ - struct idletimer_tg *timer __attribute__((aligned(8))); + /* corresponds to the idletimer_tg struct */ + unsigned long timer __attribute__((aligned(8))); };
struct idletimer_tg_info_v1 { @@ -37,6 +38,7 @@ struct idletimer_tg_info_v1 { __u8 timer_type;
/* for kernel module internal use only */ - struct idletimer_tg *timer __attribute__((aligned(8))); + /* corresponds to the idletimer_tg struct */ + unsigned long timer __attribute__((aligned(8))); }; #endif diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index db720efa811d..70d48e1d58e8 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -137,7 +137,7 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) { int ret;
- info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = (unsigned long) kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; @@ -148,36 +148,36 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) goto out_free_timer;
sysfs_attr_init(&info->timer->attr.attr); - info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); - if (!info->timer->attr.attr.name) { + ((struct idletimer_tg *)info->timer)->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!((struct idletimer_tg *)info->timer)->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + ((struct idletimer_tg *)info->timer)->attr.attr.mode = 0444; + ((struct idletimer_tg *)info->timer)->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &((struct idletimer_tg *)info->timer)->attr.attr); if (ret < 0) { pr_debug("couldn't add file to sysfs"); goto out_free_attr; }
- list_add(&info->timer->entry, &idletimer_tg_list); + list_add(&((struct idletimer_tg *)info->timer)->entry, &idletimer_tg_list);
- timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - info->timer->refcnt = 1; + timer_setup(&((struct idletimer_tg *)info->timer)->timer, idletimer_tg_expired, 0); + ((struct idletimer_tg *)info->timer)->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&((struct idletimer_tg *)info->timer)->work, idletimer_tg_work);
- mod_timer(&info->timer->timer, + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(((struct idletimer_tg *)info->timer)->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(((struct idletimer_tg *)info->timer)); out: return ret; } @@ -186,7 +186,7 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) { int ret;
- info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = (unsigned long) kmalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; @@ -196,16 +196,16 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) if (ret < 0) goto out_free_timer;
- sysfs_attr_init(&info->timer->attr.attr); - info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); - if (!info->timer->attr.attr.name) { + sysfs_attr_init(&((struct idletimer_tg *)info->timer)->attr.attr); + ((struct idletimer_tg *)info->timer)->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!((struct idletimer_tg *)info->timer)->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + ((struct idletimer_tg *)info->timer)->attr.attr.mode = 0444; + ((struct idletimer_tg *)info->timer)->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &((struct idletimer_tg *)info->timer)->attr.attr); if (ret < 0) { pr_debug("couldn't add file to sysfs"); goto out_free_attr; @@ -214,32 +214,32 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) /* notify userspace */ kobject_uevent(idletimer_tg_kobj,KOBJ_ADD);
- list_add(&info->timer->entry, &idletimer_tg_list); + list_add(&((struct idletimer_tg *)info->timer)->entry, &idletimer_tg_list); pr_debug("timer type value is %u", info->timer_type); - info->timer->timer_type = info->timer_type; - info->timer->refcnt = 1; + ((struct idletimer_tg *)info->timer)->timer_type = info->timer_type; + ((struct idletimer_tg *)info->timer)->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&((struct idletimer_tg *)info->timer)->work, idletimer_tg_work);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + if (((struct idletimer_tg *)info->timer)->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout; - alarm_init(&info->timer->alarm, ALARM_BOOTTIME, + alarm_init(&((struct idletimer_tg *)info->timer)->alarm, ALARM_BOOTTIME, idletimer_tg_alarmproc); - info->timer->alarm.data = info->timer; + ((struct idletimer_tg *)info->timer)->alarm.data = ((struct idletimer_tg *)info->timer); tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&((struct idletimer_tg *)info->timer)->alarm, tout); } else { - timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - mod_timer(&info->timer->timer, + timer_setup(&((struct idletimer_tg *)info->timer)->timer, idletimer_tg_expired, 0); + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(((struct idletimer_tg *)info->timer)->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(((struct idletimer_tg *)info->timer)); out: return ret; } @@ -255,7 +255,7 @@ static unsigned int idletimer_tg_target(struct sk_buff *skb, pr_debug("resetting timer %s, timeout period %u\n", info->label, info->timeout);
- mod_timer(&info->timer->timer, + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return XT_CONTINUE; @@ -272,11 +272,11 @@ static unsigned int idletimer_tg_target_v1(struct sk_buff *skb, pr_debug("resetting timer %s, timeout period %u\n", info->label, info->timeout);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + if (((struct idletimer_tg *)info->timer)->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&((struct idletimer_tg *)info->timer)->alarm, tout); } else { - mod_timer(&info->timer->timer, + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
@@ -318,14 +318,14 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) } mutex_lock(&list_mutex);
- info->timer = __idletimer_tg_find_by_label(info->label); - if (info->timer) { - info->timer->refcnt++; - mod_timer(&info->timer->timer, + info->timer = (unsigned long) __idletimer_tg_find_by_label(info->label); + if (((struct idletimer_tg *)info->timer)) { + ((struct idletimer_tg *)info->timer)->refcnt++; + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
pr_debug("increased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, ((struct idletimer_tg *)info->timer)->refcnt); } else { ret = idletimer_tg_create(info); if (ret < 0) { @@ -363,31 +363,31 @@ static int idletimer_tg_checkentry_v1(const struct xt_tgchk_param *par)
mutex_lock(&list_mutex);
- info->timer = __idletimer_tg_find_by_label(info->label); + info->timer = (unsigned long) __idletimer_tg_find_by_label(info->label); if (info->timer) { - if (info->timer->timer_type != info->timer_type) { + if (((struct idletimer_tg *)info->timer)->timer_type != info->timer_type) { pr_debug("Adding/Replacing rule with same label and different timer type is not allowed\n"); mutex_unlock(&list_mutex); return -EINVAL; }
- info->timer->refcnt++; + ((struct idletimer_tg *)info->timer)->refcnt++; if (info->timer_type & XT_IDLETIMER_ALARM) { /* calculate remaining expiry time */ - ktime_t tout = alarm_expires_remaining(&info->timer->alarm); + ktime_t tout = alarm_expires_remaining(&((struct idletimer_tg *)info->timer)->alarm); struct timespec64 ktimespec = ktime_to_timespec64(tout);
if (ktimespec.tv_sec > 0) { pr_debug("time_expiry_remaining %lld\n", ktimespec.tv_sec); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&((struct idletimer_tg *)info->timer)->alarm, tout); } } else { - mod_timer(&info->timer->timer, + mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); } pr_debug("increased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, ((struct idletimer_tg *)info->timer)->refcnt); } else { ret = idletimer_tg_create_v1(info); if (ret < 0) { @@ -409,18 +409,18 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--((struct idletimer_tg *)info->timer)->refcnt == 0) { pr_debug("deleting timer %s\n", info->label);
- list_del(&info->timer->entry); - timer_shutdown_sync(&info->timer->timer); - cancel_work_sync(&info->timer->work); - sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); - kfree(info->timer->attr.attr.name); - kfree(info->timer); + list_del(&((struct idletimer_tg *)info->timer)->entry); + timer_shutdown_sync(&((struct idletimer_tg *)info->timer)->timer); + cancel_work_sync(&((struct idletimer_tg *)info->timer)->work); + sysfs_remove_file(idletimer_tg_kobj, &((struct idletimer_tg *)info->timer)->attr.attr); + kfree(((struct idletimer_tg *)info->timer)->attr.attr.name); + kfree(((struct idletimer_tg *)info->timer)); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, ((struct idletimer_tg *)info->timer)->refcnt); }
mutex_unlock(&list_mutex); @@ -434,22 +434,22 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--((struct idletimer_tg *)info->timer)->refcnt == 0) { pr_debug("deleting timer %s\n", info->label);
- list_del(&info->timer->entry); - if (info->timer->timer_type & XT_IDLETIMER_ALARM) { - alarm_cancel(&info->timer->alarm); + list_del(&((struct idletimer_tg *)info->timer)->entry); + if (((struct idletimer_tg *)info->timer)->timer_type & XT_IDLETIMER_ALARM) { + alarm_cancel(&((struct idletimer_tg *)info->timer)->alarm); } else { - timer_shutdown_sync(&info->timer->timer); + timer_shutdown_sync(&((struct idletimer_tg *)info->timer)->timer); } - cancel_work_sync(&info->timer->work); - sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); - kfree(info->timer->attr.attr.name); - kfree(info->timer); + cancel_work_sync(&((struct idletimer_tg *)info->timer)->work); + sysfs_remove_file(idletimer_tg_kobj, &((struct idletimer_tg *)info->timer)->attr.attr); + kfree(((struct idletimer_tg *)info->timer)->attr.attr.name); + kfree(((struct idletimer_tg *)info->timer)); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, ((struct idletimer_tg *)info->timer)->refcnt); }
mutex_unlock(&list_mutex);
On 12/08/2024 16:11, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter/xt_IDLETIMER.h | 6 +- net/netfilter/xt_IDLETIMER.c | 132 ++++++++++---------- 2 files changed, 70 insertions(+), 68 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h index 7bfb31a66fc9..eef4aa6c6649 100644 --- a/include/uapi/linux/netfilter/xt_IDLETIMER.h +++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h @@ -25,7 +25,8 @@ struct idletimer_tg_info { char label[MAX_IDLETIMER_LABEL_SIZE]; /* for kernel module internal use only */
- struct idletimer_tg *timer __attribute__((aligned(8)));
- /* corresponds to the idletimer_tg struct */
- unsigned long timer __attribute__((aligned(8)));
}; struct idletimer_tg_info_v1 { @@ -37,6 +38,7 @@ struct idletimer_tg_info_v1 { __u8 timer_type; /* for kernel module internal use only */
- struct idletimer_tg *timer __attribute__((aligned(8)));
- /* corresponds to the idletimer_tg struct */
- unsigned long timer __attribute__((aligned(8)));
}; #endif diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index db720efa811d..70d48e1d58e8 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -137,7 +137,7 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) { int ret;
- info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL);
- info->timer = (unsigned long) kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out;
@@ -148,36 +148,36 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) goto out_free_timer; sysfs_attr_init(&info->timer->attr.attr);
- info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
- if (!info->timer->attr.attr.name) {
- ((struct idletimer_tg *)info->timer)->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
- if (!((struct idletimer_tg *)info->timer)->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; }
- info->timer->attr.attr.mode = 0444;
- info->timer->attr.show = idletimer_tg_show;
- ((struct idletimer_tg *)info->timer)->attr.attr.mode = 0444;
- ((struct idletimer_tg *)info->timer)->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr);
- ret = sysfs_create_file(idletimer_tg_kobj, &((struct idletimer_tg *)info->timer)->attr.attr); if (ret < 0) { pr_debug("couldn't add file to sysfs"); goto out_free_attr; }
- list_add(&info->timer->entry, &idletimer_tg_list);
- list_add(&((struct idletimer_tg *)info->timer)->entry, &idletimer_tg_list);
- timer_setup(&info->timer->timer, idletimer_tg_expired, 0);
- info->timer->refcnt = 1;
- timer_setup(&((struct idletimer_tg *)info->timer)->timer, idletimer_tg_expired, 0);
- ((struct idletimer_tg *)info->timer)->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work);
- INIT_WORK(&((struct idletimer_tg *)info->timer)->work, idletimer_tg_work);
- mod_timer(&info->timer->timer,
- mod_timer(&((struct idletimer_tg *)info->timer)->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return 0; out_free_attr:
- kfree(info->timer->attr.attr.name);
- kfree(((struct idletimer_tg *)info->timer)->attr.attr.name);
out_free_timer:
- kfree(info->timer);
- kfree(((struct idletimer_tg *)info->timer));
When there are so many access to the field in the same function, it would be better to use a local variable of the right type, as having so many casts gets pretty unreadable.
Kevin
[...]
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_RATEEST.h | 3 ++- net/netfilter/xt_RATEEST.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_RATEEST.h b/include/uapi/linux/netfilter/xt_RATEEST.h index 2b87a71e6266..14a45eba7f4a 100644 --- a/include/uapi/linux/netfilter/xt_RATEEST.h +++ b/include/uapi/linux/netfilter/xt_RATEEST.h @@ -11,7 +11,8 @@ struct xt_rateest_target_info { __u8 ewma_log;
/* Used internally by the kernel */ - struct xt_rateest *est __attribute__((aligned(8))); + /* Corresponds to struct xt_rateest */ + unsigned long est __attribute__((aligned(8))); };
#endif /* _XT_RATEEST_TARGET_H */ diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 80f6624e2355..15e080762db3 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c @@ -94,12 +94,12 @@ static unsigned int xt_rateest_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_rateest_target_info *info = par->targinfo; - struct gnet_stats_basic_sync *stats = &info->est->bstats; + struct gnet_stats_basic_sync *stats = &((struct xt_rateest *)info->est)->bstats;
- spin_lock_bh(&info->est->lock); + spin_lock_bh(&((struct xt_rateest *)info->est)->lock); u64_stats_add(&stats->bytes, skb->len); u64_stats_inc(&stats->packets); - spin_unlock_bh(&info->est->lock); + spin_unlock_bh(&((struct xt_rateest *)info->est)->lock);
return XT_CONTINUE; } @@ -134,7 +134,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) xt_rateest_put(par->net, est); return -EINVAL; } - info->est = est; + info->est = (unsigned long) est; return 0; }
@@ -160,7 +160,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) if (ret < 0) goto err2;
- info->est = est; + info->est = (unsigned long) est; xt_rateest_hash_insert(xn, est); mutex_unlock(&xn->hash_lock); return 0; @@ -176,7 +176,7 @@ static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par) { struct xt_rateest_target_info *info = par->targinfo;
- xt_rateest_put(par->net, info->est); + xt_rateest_put(par->net, ((struct xt_rateest *)info->est)); }
static struct xt_target xt_rateest_tg_reg __read_mostly = {
On 12/08/2024 16:11, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter/xt_RATEEST.h | 3 ++- net/netfilter/xt_RATEEST.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_RATEEST.h b/include/uapi/linux/netfilter/xt_RATEEST.h index 2b87a71e6266..14a45eba7f4a 100644 --- a/include/uapi/linux/netfilter/xt_RATEEST.h +++ b/include/uapi/linux/netfilter/xt_RATEEST.h @@ -11,7 +11,8 @@ struct xt_rateest_target_info { __u8 ewma_log; /* Used internally by the kernel */
- struct xt_rateest *est __attribute__((aligned(8)));
- /* Corresponds to struct xt_rateest */
- unsigned long est __attribute__((aligned(8)));
}; #endif /* _XT_RATEEST_TARGET_H */ diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 80f6624e2355..15e080762db3 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c @@ -94,12 +94,12 @@ static unsigned int xt_rateest_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_rateest_target_info *info = par->targinfo;
- struct gnet_stats_basic_sync *stats = &info->est->bstats;
- struct gnet_stats_basic_sync *stats = &((struct xt_rateest *)info->est)->bstats;
- spin_lock_bh(&info->est->lock);
- spin_lock_bh(&((struct xt_rateest *)info->est)->lock); u64_stats_add(&stats->bytes, skb->len); u64_stats_inc(&stats->packets);
- spin_unlock_bh(&info->est->lock);
- spin_unlock_bh(&((struct xt_rateest *)info->est)->lock);
return XT_CONTINUE; } @@ -134,7 +134,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) xt_rateest_put(par->net, est); return -EINVAL; }
info->est = est;
return 0; }info->est = (unsigned long) est;
@@ -160,7 +160,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) if (ret < 0) goto err2;
- info->est = est;
- info->est = (unsigned long) est; xt_rateest_hash_insert(xn, est); mutex_unlock(&xn->hash_lock); return 0;
@@ -176,7 +176,7 @@ static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par) { struct xt_rateest_target_info *info = par->targinfo;
- xt_rateest_put(par->net, info->est);
- xt_rateest_put(par->net, ((struct xt_rateest *)info->est));
Nit: no need for parentheses around the expression here.
Kevin
} static struct xt_target xt_rateest_tg_reg __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_TEE.h | 3 ++- net/netfilter/xt_TEE.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_TEE.h b/include/uapi/linux/netfilter/xt_TEE.h index eb854917f828..1102da7f08cf 100644 --- a/include/uapi/linux/netfilter/xt_TEE.h +++ b/include/uapi/linux/netfilter/xt_TEE.h @@ -9,7 +9,8 @@ struct xt_tee_tginfo { char oif[16];
/* used internally by the kernel */ - struct xt_tee_priv *priv __attribute__((aligned(8))); + /* Corresponds to struct xt_tee_priv */ + unsigned long priv __attribute__((aligned(8))); };
#endif /* _XT_TEE_TARGET_H */ diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index a5ebd5640457..98c6f754778c 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -37,7 +37,7 @@ static unsigned int tee_tg4(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_tee_tginfo *info = par->targinfo; - int oif = info->priv ? info->priv->oif : 0; + int oif = info->priv ? ((struct xt_tee_priv *) info->priv)->oif : 0;
nf_dup_ipv4(xt_net(par), skb, xt_hooknum(par), &info->gw.in, oif);
@@ -49,7 +49,7 @@ static unsigned int tee_tg6(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_tee_tginfo *info = par->targinfo; - int oif = info->priv ? info->priv->oif : 0; + int oif = info->priv ? ((struct xt_tee_priv *) info->priv)->oif : 0;
nf_dup_ipv6(xt_net(par), skb, xt_hooknum(par), &info->gw.in6, oif);
@@ -112,7 +112,7 @@ static int tee_tg_check(const struct xt_tgchk_param *par)
priv->tginfo = info; priv->oif = -1; - info->priv = priv; + info->priv = (unsigned long) priv;
dev = dev_get_by_name(par->net, info->oif); if (dev) { @@ -123,7 +123,7 @@ static int tee_tg_check(const struct xt_tgchk_param *par) list_add(&priv->list, &tn->priv_list); mutex_unlock(&tn->lock); } else - info->priv = NULL; + info->priv = (unsigned long) NULL;
static_key_slow_inc(&xt_tee_enabled); return 0; @@ -136,9 +136,9 @@ static void tee_tg_destroy(const struct xt_tgdtor_param *par)
if (info->priv) { mutex_lock(&tn->lock); - list_del(&info->priv->list); + list_del(&((struct xt_tee_priv *) info->priv)->list); mutex_unlock(&tn->lock); - kfree(info->priv); + kfree(((struct xt_tee_priv *) info->priv)); } static_key_slow_dec(&xt_tee_enabled); }
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_bpf.h | 6 ++++-- net/netfilter/xt_bpf.c | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h index a05adda26d3e..200835e256b0 100644 --- a/include/uapi/linux/netfilter/xt_bpf.h +++ b/include/uapi/linux/netfilter/xt_bpf.h @@ -16,7 +16,8 @@ struct xt_bpf_info { struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR];
/* only used in the kernel */ - struct bpf_prog *filter __attribute__((aligned(8))); + /* Corresponds to the bpf_prog* struct */ + unsigned long filter __attribute__((aligned(8))); };
enum xt_bpf_modes { @@ -36,7 +37,8 @@ struct xt_bpf_info_v1 { };
/* only used in the kernel */ - struct bpf_prog *filter __attribute__((aligned(8))); + /* Corresponds to the bpf_prog* struct */ + unsigned long filter __attribute__((aligned(8))); };
#endif /*_XT_BPF_H */ diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 849ac552a154..376d0c4bd5cf 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c @@ -65,23 +65,25 @@ static int bpf_mt_check(const struct xt_mtchk_param *par) { struct xt_bpf_info *info = par->matchinfo;
+ struct bpf_prog * filter_tmp = ((struct bpf_prog *)info->filter); return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem, - &info->filter); + &filter_tmp); }
static int bpf_mt_check_v1(const struct xt_mtchk_param *par) { struct xt_bpf_info_v1 *info = par->matchinfo;
+ struct bpf_prog * filter_tmp = ((struct bpf_prog *)info->filter); if (info->mode == XT_BPF_MODE_BYTECODE) return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem, - &info->filter); + &filter_tmp); else if (info->mode == XT_BPF_MODE_FD_ELF) - return __bpf_mt_check_fd(info->fd, &info->filter); + return __bpf_mt_check_fd(info->fd, &filter_tmp); else if (info->mode == XT_BPF_MODE_PATH_PINNED) - return __bpf_mt_check_path(info->path, &info->filter); + return __bpf_mt_check_path(info->path, &filter_tmp); else return -EINVAL; } @@ -90,28 +92,28 @@ static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_bpf_info *info = par->matchinfo;
- return bpf_prog_run(info->filter, skb); + return bpf_prog_run(((struct bpf_prog *)info->filter), skb); }
static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_bpf_info_v1 *info = par->matchinfo;
- return !!bpf_prog_run_save_cb(info->filter, (struct sk_buff *) skb); + return !!bpf_prog_run_save_cb(((struct bpf_prog *)info->filter), (struct sk_buff *) skb); }
static void bpf_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_bpf_info *info = par->matchinfo;
- bpf_prog_destroy(info->filter); + bpf_prog_destroy(((struct bpf_prog *)info->filter)); }
static void bpf_mt_destroy_v1(const struct xt_mtdtor_param *par) { const struct xt_bpf_info_v1 *info = par->matchinfo;
- bpf_prog_destroy(info->filter); + bpf_prog_destroy(((struct bpf_prog *)info->filter)); }
static struct xt_match bpf_mt_reg[] __read_mostly = {
On 12/08/2024 16:11, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter/xt_bpf.h | 6 ++++-- net/netfilter/xt_bpf.c | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h index a05adda26d3e..200835e256b0 100644 --- a/include/uapi/linux/netfilter/xt_bpf.h +++ b/include/uapi/linux/netfilter/xt_bpf.h @@ -16,7 +16,8 @@ struct xt_bpf_info { struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR]; /* only used in the kernel */
- struct bpf_prog *filter __attribute__((aligned(8)));
- /* Corresponds to the bpf_prog* struct */
- unsigned long filter __attribute__((aligned(8)));
}; enum xt_bpf_modes { @@ -36,7 +37,8 @@ struct xt_bpf_info_v1 { }; /* only used in the kernel */
- struct bpf_prog *filter __attribute__((aligned(8)));
- /* Corresponds to the bpf_prog* struct */
- unsigned long filter __attribute__((aligned(8)));
}; #endif /*_XT_BPF_H */ diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 849ac552a154..376d0c4bd5cf 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c @@ -65,23 +65,25 @@ static int bpf_mt_check(const struct xt_mtchk_param *par) { struct xt_bpf_info *info = par->matchinfo;
- struct bpf_prog * filter_tmp = ((struct bpf_prog *)info->filter);
A few nits: - In general, all local variables are declared in the same block (no empty line), and then an empty line is added between the declarations and the first statement. - For pointer types, there should be a space before * but not after. - I would call the variable just "filter", it's clear that it's a temporary variable.
Kevin
return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem,
&info->filter);
&filter_tmp);
} static int bpf_mt_check_v1(const struct xt_mtchk_param *par) { struct xt_bpf_info_v1 *info = par->matchinfo;
- struct bpf_prog * filter_tmp = ((struct bpf_prog *)info->filter); if (info->mode == XT_BPF_MODE_BYTECODE) return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem,
&info->filter);
else if (info->mode == XT_BPF_MODE_FD_ELF)&filter_tmp);
return __bpf_mt_check_fd(info->fd, &info->filter);
else if (info->mode == XT_BPF_MODE_PATH_PINNED)return __bpf_mt_check_fd(info->fd, &filter_tmp);
return __bpf_mt_check_path(info->path, &info->filter);
else return -EINVAL;return __bpf_mt_check_path(info->path, &filter_tmp);
} @@ -90,28 +92,28 @@ static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_bpf_info *info = par->matchinfo;
- return bpf_prog_run(info->filter, skb);
- return bpf_prog_run(((struct bpf_prog *)info->filter), skb);
} static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_bpf_info_v1 *info = par->matchinfo;
- return !!bpf_prog_run_save_cb(info->filter, (struct sk_buff *) skb);
- return !!bpf_prog_run_save_cb(((struct bpf_prog *)info->filter), (struct sk_buff *) skb);
} static void bpf_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_bpf_info *info = par->matchinfo;
- bpf_prog_destroy(info->filter);
- bpf_prog_destroy(((struct bpf_prog *)info->filter));
} static void bpf_mt_destroy_v1(const struct xt_mtdtor_param *par) { const struct xt_bpf_info_v1 *info = par->matchinfo;
- bpf_prog_destroy(info->filter);
- bpf_prog_destroy(((struct bpf_prog *)info->filter));
} static struct xt_match bpf_mt_reg[] __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_connlimit.h | 3 ++- net/netfilter/xt_connlimit.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_connlimit.h b/include/uapi/linux/netfilter/xt_connlimit.h index d4d1943dcd11..db6b67d95c94 100644 --- a/include/uapi/linux/netfilter/xt_connlimit.h +++ b/include/uapi/linux/netfilter/xt_connlimit.h @@ -27,7 +27,8 @@ struct xt_connlimit_info { __u32 flags;
/* Used internally by the kernel */ - struct nf_conncount_data *data __attribute__((aligned(8))); + /* Corresponds to the struct nf_conncount_data **/ + unsigned long data __attribute__((aligned(8))); };
#endif /* _XT_CONNLIMIT_H */ diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 5d04ef80a61d..4c0a71b47b66 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -69,7 +69,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) key[1] = zone->id; }
- connections = nf_conncount_count(net, info->data, key, tuple_ptr, + connections = nf_conncount_count(net, (struct nf_conncount_data*) info->data, key, tuple_ptr, zone); if (connections == 0) /* kmalloc failed, drop it entirely */ @@ -94,16 +94,16 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) keylen += sizeof(struct in_addr);
/* init private data */ - info->data = nf_conncount_init(par->net, par->family, keylen); + info->data = (unsigned long) nf_conncount_init(par->net, par->family, keylen);
- return PTR_ERR_OR_ZERO(info->data); + return PTR_ERR_OR_ZERO((struct nf_conncount_data*) info->data); }
static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_connlimit_info *info = par->matchinfo;
- nf_conncount_destroy(par->net, par->family, info->data); + nf_conncount_destroy(par->net, par->family, (struct nf_conncount_data*) info->data); }
static struct xt_match connlimit_mt_reg __read_mostly = {
On 12/08/2024 16:11, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter/xt_connlimit.h | 3 ++- net/netfilter/xt_connlimit.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_connlimit.h b/include/uapi/linux/netfilter/xt_connlimit.h index d4d1943dcd11..db6b67d95c94 100644 --- a/include/uapi/linux/netfilter/xt_connlimit.h +++ b/include/uapi/linux/netfilter/xt_connlimit.h @@ -27,7 +27,8 @@ struct xt_connlimit_info { __u32 flags; /* Used internally by the kernel */
- struct nf_conncount_data *data __attribute__((aligned(8)));
- /* Corresponds to the struct nf_conncount_data **/
Nit: always a space before the closing */ (hard to read otherwise).
Kevin
- unsigned long data __attribute__((aligned(8)));
}; #endif /* _XT_CONNLIMIT_H */ diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 5d04ef80a61d..4c0a71b47b66 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -69,7 +69,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) key[1] = zone->id; }
- connections = nf_conncount_count(net, info->data, key, tuple_ptr,
- connections = nf_conncount_count(net, (struct nf_conncount_data*) info->data, key, tuple_ptr, zone); if (connections == 0) /* kmalloc failed, drop it entirely */
@@ -94,16 +94,16 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) keylen += sizeof(struct in_addr); /* init private data */
- info->data = nf_conncount_init(par->net, par->family, keylen);
- info->data = (unsigned long) nf_conncount_init(par->net, par->family, keylen);
- return PTR_ERR_OR_ZERO(info->data);
- return PTR_ERR_OR_ZERO((struct nf_conncount_data*) info->data);
} static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_connlimit_info *info = par->matchinfo;
- nf_conncount_destroy(par->net, par->family, info->data);
- nf_conncount_destroy(par->net, par->family, (struct nf_conncount_data*) info->data);
} static struct xt_match connlimit_mt_reg __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_hashlimit.h | 17 +++++++++------ net/netfilter/xt_hashlimit.c | 24 +++++++++++---------- 2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_hashlimit.h b/include/uapi/linux/netfilter/xt_hashlimit.h index 721a8de6c5b3..9e9b339a475b 100644 --- a/include/uapi/linux/netfilter/xt_hashlimit.h +++ b/include/uapi/linux/netfilter/xt_hashlimit.h @@ -46,10 +46,12 @@ struct xt_hashlimit_info { struct hashlimit_cfg cfg;
/* Used internally by the kernel */ - struct xt_hashlimit_htable *hinfo; + /* Corresponds to struct xt_hashlimit_htable **/ + unsigned long hinfo; union { - void *ptr; - struct xt_hashlimit_info *master; + /* Corresponds to struct xt_hashlimit_info *, or generic void ptr*/ + unsigned long ptr; + unsigned long master; } u; };
@@ -101,7 +103,8 @@ struct xt_hashlimit_mtinfo1 { struct hashlimit_cfg1 cfg;
/* Used internally by the kernel */ - struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); + /* Corresponds to struct xt_hashlimit_htable **/ + unsigned long hinfo __attribute__((aligned(8))); };
struct xt_hashlimit_mtinfo2 { @@ -109,7 +112,8 @@ struct xt_hashlimit_mtinfo2 { struct hashlimit_cfg2 cfg;
/* Used internally by the kernel */ - struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); + /* Corresponds to struct xt_hashlimit_htable **/ + unsigned long hinfo __attribute__((aligned(8))); };
struct xt_hashlimit_mtinfo3 { @@ -117,7 +121,8 @@ struct xt_hashlimit_mtinfo3 { struct hashlimit_cfg3 cfg;
/* Used internally by the kernel */ - struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); + /* Corresponds to struct xt_hashlimit_htable **/ + unsigned long hinfo __attribute__((aligned(8))); };
#endif /* _UAPI_XT_HASHLIMIT_H */ diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 0859b8f76764..951fcaef48da 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -798,7 +798,7 @@ static bool hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_hashlimit_mtinfo1 *info = par->matchinfo; - struct xt_hashlimit_htable *hinfo = info->hinfo; + struct xt_hashlimit_htable *hinfo = (struct xt_hashlimit_htable *) info->hinfo; struct hashlimit_cfg3 cfg = {}; int ret;
@@ -813,7 +813,7 @@ static bool hashlimit_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_hashlimit_mtinfo2 *info = par->matchinfo; - struct xt_hashlimit_htable *hinfo = info->hinfo; + struct xt_hashlimit_htable *hinfo = (struct xt_hashlimit_htable *) info->hinfo; struct hashlimit_cfg3 cfg = {}; int ret;
@@ -828,7 +828,7 @@ static bool hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_hashlimit_mtinfo3 *info = par->matchinfo; - struct xt_hashlimit_htable *hinfo = info->hinfo; + struct xt_hashlimit_htable *hinfo = (struct xt_hashlimit_htable *) info->hinfo;
return hashlimit_mt_common(skb, par, hinfo, &info->cfg, 3); } @@ -912,6 +912,7 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par) struct xt_hashlimit_mtinfo1 *info = par->matchinfo; struct hashlimit_cfg3 cfg = {}; int ret; + struct xt_hashlimit_htable *hinfo_tmp = (struct xt_hashlimit_htable *)info->hinfo;
ret = xt_check_proc_name(info->name, sizeof(info->name)); if (ret) @@ -921,8 +922,7 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par) if (ret) return ret;
- return hashlimit_mt_check_common(par, &info->hinfo, - &cfg, info->name, 1); + return hashlimit_mt_check_common(par, &hinfo_tmp, &cfg, info->name, 1); }
static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) @@ -930,6 +930,7 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) struct xt_hashlimit_mtinfo2 *info = par->matchinfo; struct hashlimit_cfg3 cfg = {}; int ret; + struct xt_hashlimit_htable *hinfo_tmp = (struct xt_hashlimit_htable *)info->hinfo;
ret = xt_check_proc_name(info->name, sizeof(info->name)); if (ret) @@ -939,7 +940,7 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) if (ret) return ret;
- return hashlimit_mt_check_common(par, &info->hinfo, + return hashlimit_mt_check_common(par, &hinfo_tmp, &cfg, info->name, 2); }
@@ -947,34 +948,35 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) { struct xt_hashlimit_mtinfo3 *info = par->matchinfo; int ret; + struct xt_hashlimit_htable *hinfo_tmp = (struct xt_hashlimit_htable *)info->hinfo;
ret = xt_check_proc_name(info->name, sizeof(info->name)); if (ret) return ret;
- return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg, - info->name, 3); + return hashlimit_mt_check_common(par, &hinfo_tmp, &info->cfg, + info->name, 3); }
static void hashlimit_mt_destroy_v2(const struct xt_mtdtor_param *par) { const struct xt_hashlimit_mtinfo2 *info = par->matchinfo;
- htable_put(info->hinfo); + htable_put((struct xt_hashlimit_htable *)info->hinfo); }
static void hashlimit_mt_destroy_v1(const struct xt_mtdtor_param *par) { const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
- htable_put(info->hinfo); + htable_put((struct xt_hashlimit_htable *)info->hinfo); }
static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_hashlimit_mtinfo3 *info = par->matchinfo;
- htable_put(info->hinfo); + htable_put((struct xt_hashlimit_htable *)info->hinfo); }
static struct xt_match hashlimit_mt_reg[] __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_limit.h | 3 ++- net/netfilter/xt_limit.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_limit.h b/include/uapi/linux/netfilter/xt_limit.h index 1d6e4ce9a646..5b52b5714795 100644 --- a/include/uapi/linux/netfilter/xt_limit.h +++ b/include/uapi/linux/netfilter/xt_limit.h @@ -20,6 +20,7 @@ struct xt_rateinfo { __u32 credit; /* moved to xt_limit_priv */ __u32 credit_cap, cost;
- struct xt_limit_priv *master; + /* Corresponds to the xt_limit_priv* struct */ + unsigned long master; }; #endif /*_XT_RATE_H*/ diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 8b4fd27857f2..01f2dcd1f567 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c @@ -63,7 +63,7 @@ static bool limit_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_rateinfo *r = par->matchinfo; - struct xt_limit_priv *priv = r->master; + struct xt_limit_priv *priv = (struct xt_limit_priv *)r->master; unsigned long now; u32 old_credit, new_credit, credit_increase = 0; bool ret; @@ -120,7 +120,7 @@ static int limit_mt_check(const struct xt_mtchk_param *par) return -ENOMEM;
/* For SMP, we only want to use one set of state. */ - r->master = priv; + r->master = (unsigned long) priv; /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * 128. */ priv->prev = jiffies; @@ -137,7 +137,7 @@ static void limit_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_rateinfo *info = par->matchinfo;
- kfree(info->master); + kfree((struct xt_limit_priv *)info->master); }
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_nfacct.h | 6 ++++-- net/netfilter/xt_nfacct.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_nfacct.h b/include/uapi/linux/netfilter/xt_nfacct.h index b5123ab8d54a..1b55f8b6d255 100644 --- a/include/uapi/linux/netfilter/xt_nfacct.h +++ b/include/uapi/linux/netfilter/xt_nfacct.h @@ -8,12 +8,14 @@ struct nf_acct;
struct xt_nfacct_match_info { char name[NFACCT_NAME_MAX]; - struct nf_acct *nfacct; + /* Corresponds to the nf_acct* struct */ + unsigned long nfacct; };
struct xt_nfacct_match_info_v1 { char name[NFACCT_NAME_MAX]; - struct nf_acct *nfacct __attribute__((aligned(8))); + /* Corresponds to the nf_acct* struct */ + unsigned long nfacct __attribute__((aligned(8))); };
#endif /* _XT_NFACCT_MATCH_H */ diff --git a/net/netfilter/xt_nfacct.c b/net/netfilter/xt_nfacct.c index 7c6bf1c16813..0a20b8fbbd4a 100644 --- a/net/netfilter/xt_nfacct.c +++ b/net/netfilter/xt_nfacct.c @@ -23,9 +23,9 @@ static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par) int overquota; const struct xt_nfacct_match_info *info = par->targinfo;
- nfnl_acct_update(skb, info->nfacct); + nfnl_acct_update(skb, (struct nf_acct *)info->nfacct);
- overquota = nfnl_acct_overquota(xt_net(par), info->nfacct); + overquota = nfnl_acct_overquota(xt_net(par), (struct nf_acct *)info->nfacct);
return overquota != NFACCT_UNDERQUOTA; } @@ -42,7 +42,7 @@ nfacct_mt_checkentry(const struct xt_mtchk_param *par) info->name); return -ENOENT; } - info->nfacct = nfacct; + info->nfacct = (unsigned long) nfacct; return 0; }
@@ -51,7 +51,7 @@ nfacct_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_nfacct_match_info *info = par->matchinfo;
- nfnl_acct_put(info->nfacct); + nfnl_acct_put((struct nf_acct *)info->nfacct); }
static struct xt_match nfacct_mt_reg[] __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_quota.h | 3 ++- net/netfilter/xt_quota.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_quota.h b/include/uapi/linux/netfilter/xt_quota.h index f3ba5d9e58b6..31e8c4dc6711 100644 --- a/include/uapi/linux/netfilter/xt_quota.h +++ b/include/uapi/linux/netfilter/xt_quota.h @@ -17,7 +17,8 @@ struct xt_quota_info { __aligned_u64 quota;
/* Used internally by the kernel */ - struct xt_quota_priv *master; + /* Corresponds to xt_quota_priv* */ + unsigned long master; };
#endif /* _XT_QUOTA_H */ diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c index 4452cc93b990..d3d682314b43 100644 --- a/net/netfilter/xt_quota.c +++ b/net/netfilter/xt_quota.c @@ -27,7 +27,7 @@ static bool quota_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct xt_quota_info *q = (void *)par->matchinfo; - struct xt_quota_priv *priv = q->master; + struct xt_quota_priv *priv = (struct xt_quota_priv *)q->master; bool ret = q->flags & XT_QUOTA_INVERT;
spin_lock_bh(&priv->lock); @@ -50,12 +50,12 @@ static int quota_mt_check(const struct xt_mtchk_param *par) if (q->flags & ~XT_QUOTA_MASK) return -EINVAL;
- q->master = kmalloc(sizeof(*q->master), GFP_KERNEL); - if (q->master == NULL) + q->master = (unsigned long) kmalloc(sizeof(struct xt_quota_priv), GFP_KERNEL); + if (((struct xt_quota_priv*)q->master) == NULL) return -ENOMEM;
- spin_lock_init(&q->master->lock); - q->master->quota = q->quota; + spin_lock_init(&((struct xt_quota_priv*)q->master)->lock); + ((struct xt_quota_priv*)q->master)->quota = q->quota; return 0; }
@@ -63,7 +63,7 @@ static void quota_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_quota_info *q = par->matchinfo;
- kfree(q->master); + kfree((struct xt_quota_priv*)q->master); }
static struct xt_match quota_mt_reg __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_rateest.h | 5 +++-- net/netfilter/xt_rateest.c | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_rateest.h b/include/uapi/linux/netfilter/xt_rateest.h index 52a37bdc1837..5ae0eccb857a 100644 --- a/include/uapi/linux/netfilter/xt_rateest.h +++ b/include/uapi/linux/netfilter/xt_rateest.h @@ -32,8 +32,9 @@ struct xt_rateest_match_info { __u32 pps2;
/* Used internally by the kernel */ - struct xt_rateest *est1 __attribute__((aligned(8))); - struct xt_rateest *est2 __attribute__((aligned(8))); + /* Corresponds to struct xt_rateest* */ + unsigned long est1 __attribute__((aligned(8))); + unsigned long est2 __attribute__((aligned(8))); };
#endif /* _XT_RATEEST_MATCH_H */ diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c index 72324bd976af..45a798be5de6 100644 --- a/net/netfilter/xt_rateest.c +++ b/net/netfilter/xt_rateest.c @@ -19,7 +19,7 @@ xt_rateest_mt(const struct sk_buff *skb, struct xt_action_param *par) u_int32_t bps1, bps2, pps1, pps2; bool ret = true;
- gen_estimator_read(&info->est1->rate_est, &sample); + gen_estimator_read(&((struct xt_rateest *)info->est1)->rate_est, &sample);
if (info->flags & XT_RATEEST_MATCH_DELTA) { bps1 = info->bps1 >= sample.bps ? info->bps1 - sample.bps : 0; @@ -33,7 +33,7 @@ xt_rateest_mt(const struct sk_buff *skb, struct xt_action_param *par) bps2 = info->bps2; pps2 = info->pps2; } else { - gen_estimator_read(&info->est2->rate_est, &sample); + gen_estimator_read(&((struct xt_rateest *)info->est2)->rate_est, &sample);
if (info->flags & XT_RATEEST_MATCH_DELTA) { bps2 = info->bps2 >= sample.bps ? info->bps2 - sample.bps : 0; @@ -103,8 +103,8 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) goto err2; }
- info->est1 = est1; - info->est2 = est2; + info->est1 = (unsigned long) est1; + info->est2 = (unsigned long) est2; return 0;
err2: @@ -117,9 +117,9 @@ static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par) { struct xt_rateest_match_info *info = par->matchinfo;
- xt_rateest_put(par->net, info->est1); + xt_rateest_put(par->net, (struct xt_rateest *)info->est1); if (info->est2) - xt_rateest_put(par->net, info->est2); + xt_rateest_put(par->net, (struct xt_rateest *)info->est2); }
static struct xt_match xt_rateest_mt_reg __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_statistic.h | 3 ++- net/netfilter/xt_statistic.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_statistic.h b/include/uapi/linux/netfilter/xt_statistic.h index bbce6fcb26e3..cb572ada7876 100644 --- a/include/uapi/linux/netfilter/xt_statistic.h +++ b/include/uapi/linux/netfilter/xt_statistic.h @@ -31,7 +31,8 @@ struct xt_statistic_info { __u32 count; /* unused */ } nth; } u; - struct xt_statistic_priv *master __attribute__((aligned(8))); + /* Corresponds to struct xt_statistic_priv * */ + unsigned long master __attribute__((aligned(8))); };
#endif /* _XT_STATISTIC_H */ diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index b26c1dcfc27b..73ef243d07f7 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c @@ -39,9 +39,9 @@ statistic_mt(const struct sk_buff *skb, struct xt_action_param *par) break; case XT_STATISTIC_MODE_NTH: do { - oval = atomic_read(&info->master->count); + oval = atomic_read(&((struct xt_statistic_priv *)info->master)->count); nval = (oval == info->u.nth.every) ? 0 : oval + 1; - } while (atomic_cmpxchg(&info->master->count, oval, nval) != oval); + } while (atomic_cmpxchg(&((struct xt_statistic_priv *)info->master)->count, oval, nval) != oval); if (nval == 0) ret = !ret; break; @@ -58,10 +58,10 @@ static int statistic_mt_check(const struct xt_mtchk_param *par) info->flags & ~XT_STATISTIC_MASK) return -EINVAL;
- info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); - if (info->master == NULL) + info->master = (unsigned long) kzalloc(sizeof(struct xt_statistic_priv), GFP_KERNEL); + if ((struct xt_statistic_priv*)info->master == NULL) return -ENOMEM; - atomic_set(&info->master->count, info->u.nth.count); + atomic_set(&((struct xt_statistic_priv *)info->master)->count, info->u.nth.count);
return 0; } @@ -70,7 +70,7 @@ static void statistic_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_statistic_info *info = par->matchinfo;
- kfree(info->master); + kfree((struct xt_statistic_priv*)info->master); }
static struct xt_match xt_statistic_mt_reg __read_mostly = {
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
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..aa1b2ea328dd 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 * */ + unsigned long 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 * */ + unsigned long 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 * */ + unsigned long 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 * */ + unsigned long 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 * */ + unsigned long 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..1dca9fd5542b 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] = (unsigned long) &initial_chain, }, .entries = (char *)&initial_chain, }; diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index dacd81b12e62..652bd92fb832 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] = (unsigned long) &initial_chains[0], + [NF_BR_FORWARD] = (unsigned long) &initial_chains[1], + [NF_BR_LOCAL_OUT] = (unsigned long) &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..78ad50a52b1c 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] = (unsigned long) &initial_chains[0], + [NF_BR_LOCAL_OUT] = (unsigned long) &initial_chains[1], + [NF_BR_POST_ROUTING] = (unsigned long) &initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 99d82676f780..a6df9a258b4f 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 = (unsigned long) 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 = (unsigned long) 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 = (unsigned long) 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))) @@ -1636,7 +1636,7 @@ static int ebt_compat_match_offset(const struct xt_match *match, static int compat_match_to_user(struct ebt_entry_match *m, void __user **dstptr, 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; @@ -1668,7 +1668,7 @@ static int compat_target_to_user(struct ebt_entry_target *t, void __user **dstptr, 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; @@ -1762,14 +1762,14 @@ static int compat_copy_entry_to_user(struct ebt_entry *e, void __user **dstptr,
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; } @@ -1794,7 +1794,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; @@ -1864,7 +1864,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)))
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h index ff6599494fe6..9bdc308d70d0 100644 --- a/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h +++ b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h @@ -32,7 +32,8 @@ struct ipt_clusterip_tgt_info { __u32 hash_initval;
/* Used internally by the kernel */ - struct clusterip_config *config; + /* Corresponds to struct clusterip_config * */ + unsigned long config; };
#endif /*_IPT_CLUSTERIP_H_target*/
On 12/08/2024 16:11, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be unsigned longs.
Signed-off-by: Joshua Lant joshualant@gmail.com
include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h index ff6599494fe6..9bdc308d70d0 100644 --- a/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h +++ b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h @@ -32,7 +32,8 @@ struct ipt_clusterip_tgt_info { __u32 hash_initval; /* Used internally by the kernel */
- struct clusterip_config *config;
- /* Corresponds to struct clusterip_config * */
- unsigned long config;
This struct has become unused since support for clusterip was dropped [1]. I assume that the uapi header wasn't removed yet to avoid potential breakage, but I think we can ignore its contents (i.e. drop this patch).
Kevin
[1] https://lore.kernel.org/all/20230118123208.17167-6-fw@strlen.de/
}; #endif /*_IPT_CLUSTERIP_H_target*/
On 12/08/2024 16:11, Joshua Lant wrote:
Many of the uapi structs in the netfilter subsystem contain kernel pointers which cause alignment issues when the kernel parses netlink messages. Change these pointers to use unsigned longs, and cast to a pointer when used inside the kernel.
Thank you for putting together these patches! The general principle looks good to me (I've replied to a few patches with some nits).
That said, looking at all these added casts from/to unsigned long makes me realise this might not be such a good idea... As things stand, this should work as expected. The issue is that we are now baking into the uapi the assumption that kernel pointers are the size of unsigned long, in other words that the kernel is not itself purecap. If someone were to later try and move to a purecap kernel, that would immediately break.
I don't think there's a pretty solution to this, because fundamentally those pointers should never have ended up in uapi structs. My feeling is that the least bad option is to make those fields the size of a user pointer. This is wasteful on a hybrid kernel, but it is compatible with any kernel ABI, and another upside is that there is no uapi change (i.e. an application built against old uapi headers would still work fine). That could be done by simply adding __user to the field type, but this gets ugly on the kernel side in terms of casting. What is probably preferable is to define a new type, similar to __kernel_uintptr_t except that it is the size of an unsigned long in !PCuABI (instead of __u64). Its usage is quite specific to netfilter so we could name it accordingly, e.g. __nf_kptr_t. It's quite tricky to get the #ifdef'ing right but in principle it should be exactly the same as commit "uapi: types.h: define __kernel_uintptr_t type" [1], adding the type to netfilter kernel/uapi headers instead.
Once this is done your series should remain broadly the same - just replace unsigned long with __nf_kptr_t in all the changes.
Really sorry to make you change the approach again, I should have considered the kernel ABI assumption earlier.
Kevin
[1] https://git.morello-project.org/morello/kernel/linux/-/commit/f8a9c31d0342b
For more information on the necessity of these patches, see discussion in this thread:
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/...
Joshua Lant (16): x_tables.h: remove kernel pointer from uapi xt_entry_match struct x_tables.h: remove kernel pointer from uapi xt_entry_target struct xt_CT: remove pointer from uapi struct xt_IDLETIMER: remove pointer from uapi struct xt_RATEEST: remove pointer from uapi struct xt_TEE: remove pointer from uapi struct xt_bpf: remove pointer from uapi struct xt_connlimit: remove pointer from uapi struct xt_hashlimit: remove pointer from uapi struct xt_limit: remove pointer from uapi struct xt_nfacct: remove pointer from uapi struct xt_quota: remove pointer from uapi struct xt_rateest: remove pointer from uapi struct xt_statistic: remove pointer from uapi struct ebtables: remove pointer from uapi struct ipt_CLUSTERIP: remove pointer from uapi struct
include/uapi/linux/netfilter/x_tables.h | 4 +- include/uapi/linux/netfilter/xt_CT.h | 4 +- include/uapi/linux/netfilter/xt_IDLETIMER.h | 6 +- include/uapi/linux/netfilter/xt_RATEEST.h | 3 +- include/uapi/linux/netfilter/xt_TEE.h | 3 +- include/uapi/linux/netfilter/xt_bpf.h | 6 +- include/uapi/linux/netfilter/xt_connlimit.h | 3 +- include/uapi/linux/netfilter/xt_hashlimit.h | 17 ++- include/uapi/linux/netfilter/xt_limit.h | 3 +- include/uapi/linux/netfilter/xt_nfacct.h | 6 +- include/uapi/linux/netfilter/xt_quota.h | 3 +- include/uapi/linux/netfilter/xt_rateest.h | 5 +- include/uapi/linux/netfilter/xt_statistic.h | 3 +- .../uapi/linux/netfilter_bridge/ebtables.h | 15 +- .../uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 3 +- 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 ++++----- net/ipv4/netfilter/arp_tables.c | 22 +-- net/ipv4/netfilter/ip_tables.c | 44 +++--- net/ipv6/netfilter/ip6_tables.c | 44 +++--- net/netfilter/x_tables.c | 20 +-- net/netfilter/xt_CT.c | 10 +- net/netfilter/xt_IDLETIMER.c | 132 +++++++++--------- net/netfilter/xt_RATEEST.c | 12 +- net/netfilter/xt_TCPMSS.c | 2 +- net/netfilter/xt_TEE.c | 12 +- net/netfilter/xt_bpf.c | 18 +-- net/netfilter/xt_connlimit.c | 8 +- net/netfilter/xt_hashlimit.c | 24 ++-- net/netfilter/xt_limit.c | 6 +- net/netfilter/xt_nfacct.c | 8 +- net/netfilter/xt_quota.c | 12 +- net/netfilter/xt_rateest.c | 12 +- net/netfilter/xt_statistic.c | 12 +- 36 files changed, 294 insertions(+), 266 deletions(-)
linux-morello@op-lists.linaro.org