Changes from v2:
- [01/17] Updated first commit comment to make more sense to the reader. - [XX/17] Numerous formatting nits fixed. - [05/17] Fixed up local assignment and functional regression found. - [08/17] Fixed up functional regression found.
Requested changes not addressed:
In patch [01/17]:
Do we really have to duplicate the typedefs here? There are already quite a few headers including <linux/netfilter.h> under include/uapi/linux/netfilter/ so including it in x_tables.h too shouldn't be too problematic.
Unfortunately this duplication is required. I encountered many issues building when I tried this initially before the last patch submission. Presumably this is an artefact of xtables being deprecated by nftables? Many definitions are duplicated between these two headers.
Many thanks,
Josh
Joshua Lant (17): netfilter: Create new type for kernel pointers. 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 xtables: move include to headers
include/linux/netfilter.h | 6 + include/uapi/linux/netfilter.h | 8 + include/uapi/linux/netfilter/x_tables.h | 12 +- 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 | 7 +- 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 | 4 +- .../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 ++++---- 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 | 143 ++++++++++-------- net/netfilter/xt_RATEEST.c | 12 +- net/netfilter/xt_TCPMSS.c | 2 +- net/netfilter/xt_TEE.c | 12 +- net/netfilter/xt_bpf.c | 19 +-- 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 | 13 +- 37 files changed, 327 insertions(+), 267 deletions(-)
In the netfilter subsystem there are many structs inside the UAPI headers which contain kernel pointers. This causes misalignment between userspace and kernel space of these structures when using the PCuABI, due to the differing sizes of the pointer in kernel space, and the capability in userspace. This leads to issues with some netlink messages sent between user/kernel space.
In order to fix this, we require a new type which is the same size from the perspective of both the user and the kernel, and is able to hold a kernel pointer regardless of the ABI which is being used (non-purecap, hybrid pc-userspace/non-pc kernel, or a fully purecap kernel and userpsace).
In order to achieve this we create a new type which is the size of a capability when using CONFIG_CHERI_PURECAP_UABI, and the size of a pointer if not. We will then replace the kernel pointers in the UAPI structs with this new type. Doing this will maintain consistent struct sizing, even if a fully purecap kernel is used.
The drawback to this approach is that this method is unnecessary in the case where we have a purecap userspace and non-purecap kernel, since the kernel pointer in the structs are never actually touched by userspace, and so are not required to be the size of a capability. However, it is necessary to guarantee that the UAPI remains stable no matter what the kernel ABI uses.
The use of x_tables.h and netfilter.h appears to be mutually exclusive within the kernel.This is why it is required to add the new definition in both netfilter.h and x_tables.h. Since many conflicts between definitions exist when including netfilter.h in x_tables.h. This overlap is presumably is an artefact of xtables being superseded by nftables.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/linux/netfilter.h | 6 ++++++ include/uapi/linux/netfilter.h | 8 ++++++++ include/uapi/linux/netfilter/x_tables.h | 8 ++++++++ 3 files changed, 22 insertions(+)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 80900d910992..3041b4b78be9 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -17,6 +17,12 @@ #include <linux/sockptr.h> #include <net/net_namespace.h>
+#ifdef CONFIG_CHERI_PURECAP_UABI +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif + static inline int NF_DROP_GETERR(int verdict) { return -(verdict >> NF_VERDICT_QBITS); diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h index 5a79ccb76701..bb793b70d64c 100644 --- a/include/uapi/linux/netfilter.h +++ b/include/uapi/linux/netfilter.h @@ -7,6 +7,14 @@ #include <linux/in.h> #include <linux/in6.h>
+#ifndef __KERNEL__ +#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif +#endif + /* Responses from hook functions. */ #define NF_DROP 0 #define NF_ACCEPT 1 diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h index 796af83a963a..e695b6d34a6f 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -8,6 +8,14 @@ #define XT_EXTENSION_MAXNAMELEN 29 #define XT_TABLE_MAXNAMELEN 32
+#ifndef __KERNEL__ +#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif +#endif + struct xt_entry_match { union { struct {
Kernel pointer in uapi struct causes alignment issues moving between user-space and kernel-space. Change this to new __nf_kptr_t type 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 e695b6d34a6f..4763cc54ed2f 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -29,7 +29,7 @@ struct xt_entry_match { __u16 match_size;
/* Used inside the kernel */ - struct xt_match *match; + __nf_kptr_t match; } kernel;
/* Total length */ diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a54c54d4ba9c..486ff5eda6d7 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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..9a128c7a88f3 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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..de4f5ba7b366 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;
Kernel pointer in uapi struct causes alignment issues moving between user-space and kernel-space. Change this to new __nf_kptr_t type 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 4763cc54ed2f..f42e1b1022ae 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -52,7 +52,7 @@ struct xt_entry_target { __u16 target_size;
/* Used inside the kernel */ - struct xt_target *target; + __nf_kptr_t target; } kernel;
/* Total length */ diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index fb6eb846c381..0c5f3e11bfbe 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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 486ff5eda6d7..9c1fe1513b3e 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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 9a128c7a88f3..6855b1957a08 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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 de4f5ba7b366..6d6a5d6bbb80 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 __nf_kptr_t.
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..debae789161a 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))); + __nf_kptr_t 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))); + __nf_kptr_t ct __attribute__((aligned(8))); };
#endif /* _XT_CT_H */ diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 2be2f7a7b60f..24127c1a1c1a 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 = (__nf_kptr_t)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 __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_IDLETIMER.h | 6 +- net/netfilter/xt_IDLETIMER.c | 143 +++++++++++--------- 2 files changed, 81 insertions(+), 68 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h index 7bfb31a66fc9..5094073607f6 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 */ + __nf_kptr_t 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 */ + __nf_kptr_t timer __attribute__((aligned(8))); }; #endif diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index db720efa811d..f0253e5e5f17 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -136,48 +136,50 @@ static int idletimer_check_sysfs_name(const char *name, unsigned int size) static int idletimer_tg_create(struct idletimer_tg_info *info) { int ret; + struct idletimer_tg *timer;
- info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; } + timer = (struct idletimer_tg *)info->timer;
ret = idletimer_check_sysfs_name(info->label, sizeof(info->label)); 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) { + timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!timer->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + timer->attr.attr.mode = 0444; + timer->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &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(&timer->entry, &idletimer_tg_list);
- timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - info->timer->refcnt = 1; + timer_setup(&timer->timer, idletimer_tg_expired, 0); + timer->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&timer->work, idletimer_tg_work);
- mod_timer(&info->timer->timer, + mod_timer(&timer->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(timer->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(timer); out: return ret; } @@ -185,27 +187,29 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) { int ret; + struct idletimer_tg *timer;
- info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = kmalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; } + timer = (struct idletimer_tg *)info->timer;
ret = idletimer_check_sysfs_name(info->label, sizeof(info->label)); 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(&timer->attr.attr); + timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!timer->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + timer->attr.attr.mode = 0444; + timer->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &timer->attr.attr); if (ret < 0) { pr_debug("couldn't add file to sysfs"); goto out_free_attr; @@ -214,32 +218,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(&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; + timer->timer_type = info->timer_type; + timer->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&timer->work, idletimer_tg_work);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + if (timer->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout; - alarm_init(&info->timer->alarm, ALARM_BOOTTIME, + alarm_init(&timer->alarm, ALARM_BOOTTIME, idletimer_tg_alarmproc); - info->timer->alarm.data = info->timer; + timer->alarm.data = timer; tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&timer->alarm, tout); } else { - timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - mod_timer(&info->timer->timer, + timer_setup(&timer->timer, idletimer_tg_expired, 0); + mod_timer(&timer->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(timer->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(timer); out: return ret; } @@ -255,7 +259,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; @@ -268,15 +272,16 @@ static unsigned int idletimer_tg_target_v1(struct sk_buff *skb, const struct xt_action_param *par) { const struct idletimer_tg_info_v1 *info = par->targinfo; + struct idletimer_tg *timer = (struct idletimer_tg *)info->timer;
pr_debug("resetting timer %s, timeout period %u\n", info->label, info->timeout);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + if (timer->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&timer->alarm, tout); } else { - mod_timer(&info->timer->timer, + mod_timer(&timer->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
@@ -307,6 +312,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) { struct idletimer_tg_info *info = par->targinfo; int ret; + struct idletimer_tg *timer;
pr_debug("checkentry targinfo%s\n", info->label);
@@ -318,14 +324,15 @@ 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 = (__nf_kptr_t)__idletimer_tg_find_by_label(info->label); + timer = (struct idletimer_tg *)info->timer; + if (timer) { + timer->refcnt++; + mod_timer(&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, timer->refcnt); } else { ret = idletimer_tg_create(info); if (ret < 0) { @@ -343,6 +350,7 @@ static int idletimer_tg_checkentry_v1(const struct xt_tgchk_param *par) { struct idletimer_tg_info_v1 *info = par->targinfo; int ret; + struct idletimer_tg *timer;
pr_debug("checkentry targinfo%s\n", info->label);
@@ -363,31 +371,32 @@ 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 = (__nf_kptr_t)__idletimer_tg_find_by_label(info->label); + timer = (struct idletimer_tg *)info->timer; if (info->timer) { - if (info->timer->timer_type != info->timer_type) { + if (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++; + 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(&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(&timer->alarm, tout); } } else { - mod_timer(&info->timer->timer, + mod_timer(&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, timer->refcnt); } else { ret = idletimer_tg_create_v1(info); if (ret < 0) { @@ -404,23 +413,24 @@ static int idletimer_tg_checkentry_v1(const struct xt_tgchk_param *par) static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) { const struct idletimer_tg_info *info = par->targinfo; + struct idletimer_tg *timer = (struct idletimer_tg *)info->timer;
pr_debug("destroy targinfo %s\n", info->label);
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--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(&timer->entry); + timer_shutdown_sync(&timer->timer); + cancel_work_sync(&timer->work); + sysfs_remove_file(idletimer_tg_kobj, &timer->attr.attr); + kfree(timer->attr.attr.name); + kfree(timer); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, timer->refcnt); }
mutex_unlock(&list_mutex); @@ -429,27 +439,28 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par) { const struct idletimer_tg_info_v1 *info = par->targinfo; + struct idletimer_tg *timer = (struct idletimer_tg *)info->timer;
pr_debug("destroy targinfo %s\n", info->label);
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--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(&timer->entry); + if (timer->timer_type & XT_IDLETIMER_ALARM) { + alarm_cancel(&timer->alarm); } else { - timer_shutdown_sync(&info->timer->timer); + timer_shutdown_sync(&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(&timer->work); + sysfs_remove_file(idletimer_tg_kobj, &timer->attr.attr); + kfree(timer->attr.attr.name); + kfree(timer); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, timer->refcnt); }
mutex_unlock(&list_mutex);
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- 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..4b935d785a41 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 */ + __nf_kptr_t 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..a3890209cbd2 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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 morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- 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..c7594753171c 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 */ + __nf_kptr_t 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..ed6a4e0cc5dc 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 = (__nf_kptr_t)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 = (__nf_kptr_t)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 __nf_kptr_t.
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..f283619a6fef 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 */ + __nf_kptr_t 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 */ + __nf_kptr_t filter __attribute__((aligned(8))); };
#endif /*_XT_BPF_H */ diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 849ac552a154..132465585cff 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c @@ -64,24 +64,26 @@ static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret) static int bpf_mt_check(const struct xt_mtchk_param *par) { struct xt_bpf_info *info = par->matchinfo; + struct bpf_prog **filter = (struct bpf_prog **)&info->filter;
return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem, - &info->filter); + filter); }
static int bpf_mt_check_v1(const struct xt_mtchk_param *par) { struct xt_bpf_info_v1 *info = par->matchinfo; + struct bpf_prog **filter = (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); 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); 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); 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 morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- 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..6531e9b89c2f 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 * */ + __nf_kptr_t data __attribute__((aligned(8))); };
#endif /* _XT_CONNLIMIT_H */ diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 5d04ef80a61d..e7a043f211a9 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 = (__nf_kptr_t)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 __nf_kptr_t.
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..8b1fdb70d996 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 * */ + __nf_kptr_t hinfo; union { - void *ptr; - struct xt_hashlimit_info *master; + /* Corresponds to struct xt_hashlimit_info *, or generic void ptr */ + __nf_kptr_t ptr; + __nf_kptr_t 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 * */ + __nf_kptr_t 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 * */ + __nf_kptr_t 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 * */ + __nf_kptr_t 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..2f3e71220fb7 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 __nf_kptr_t.
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..3a5417b9bf42 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 */ + __nf_kptr_t master; }; #endif /*_XT_RATE_H*/ diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 8b4fd27857f2..4968361edde6 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 = (__nf_kptr_t)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 __nf_kptr_t.
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..5f560d3ae3b2 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 */ + __nf_kptr_t 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 */ + __nf_kptr_t 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..bf1ff0fb04b8 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 = (__nf_kptr_t)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 __nf_kptr_t.
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..550e70f82435 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* */ + __nf_kptr_t master; };
#endif /* _XT_QUOTA_H */ diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c index 4452cc93b990..14d3946e1be4 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 = (__nf_kptr_t)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 __nf_kptr_t.
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..3da80dcbf9b6 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* */ + __nf_kptr_t est1 __attribute__((aligned(8))); + __nf_kptr_t 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..ae499981f961 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 = (__nf_kptr_t)est1; + info->est2 = (__nf_kptr_t)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 __nf_kptr_t.
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..330c1d28edd2 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 * */ + __nf_kptr_t master __attribute__((aligned(8))); };
#endif /* _XT_STATISTIC_H */ diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index b26c1dcfc27b..ae9cfc206604 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 = (__nf_kptr_t)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 __nf_kptr_t.
Signed-off-by: Joshua Lant joshualant@gmail.com --- .../uapi/linux/netfilter_bridge/ebtables.h | 15 +++-- net/bridge/netfilter/ebtable_broute.c | 2 +- net/bridge/netfilter/ebtable_filter.c | 6 +- net/bridge/netfilter/ebtable_nat.c | 6 +- net/bridge/netfilter/ebtables.c | 64 +++++++++---------- 5 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h index 4ff328f3d339..7d4bd355e616 100644 --- a/include/uapi/linux/netfilter_bridge/ebtables.h +++ b/include/uapi/linux/netfilter_bridge/ebtables.h @@ -65,11 +65,13 @@ struct ebt_replace_kernel { /* total size of the entries */ unsigned int entries_size; /* start of the chains */ - struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; + /* Corresponds to struct ebt_entries * */ + __nf_kptr_t hook_entry[NF_BR_NUMHOOKS]; /* nr of counters userspace expects back */ unsigned int num_counters; /* where the kernel will put the old counters */ - struct ebt_counter *counters; + /* Corresponds to struct ebt_counter * */ + __nf_kptr_t counters; char *entries; };
@@ -125,7 +127,8 @@ struct ebt_entry_match { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_match *match; + /* Corresponds to struct xt_match * */ + __nf_kptr_t match; } u; /* size of data */ unsigned int match_size; @@ -138,7 +141,8 @@ struct ebt_entry_watcher { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_target *watcher; + /* Corresponds to struct xt_target * */ + __nf_kptr_t watcher; } u; /* size of data */ unsigned int watcher_size; @@ -151,7 +155,8 @@ struct ebt_entry_target { char name[EBT_EXTENSION_MAXNAMELEN]; __u8 revision; }; - struct xt_target *target; + /* Corresponds to struct xt_target * */ + __nf_kptr_t target; } u; /* size of data */ unsigned int target_size; diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 741360219552..e85fc0e28674 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -31,7 +31,7 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = 1 << NF_BR_BROUTING, .entries_size = sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_BROUTING] = &initial_chain, + [NF_BR_BROUTING] = (__nf_kptr_t)&initial_chain, }, .entries = (char *)&initial_chain, }; diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index dacd81b12e62..57e968ed477a 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = FILTER_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_LOCAL_IN] = &initial_chains[0], - [NF_BR_FORWARD] = &initial_chains[1], - [NF_BR_LOCAL_OUT] = &initial_chains[2], + [NF_BR_LOCAL_IN] = (__nf_kptr_t)&initial_chains[0], + [NF_BR_FORWARD] = (__nf_kptr_t)&initial_chains[1], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t)&initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 0f2a8c6118d4..e952e56e1b46 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = NAT_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_PRE_ROUTING] = &initial_chains[0], - [NF_BR_LOCAL_OUT] = &initial_chains[1], - [NF_BR_POST_ROUTING] = &initial_chains[2], + [NF_BR_PRE_ROUTING] = (__nf_kptr_t)&initial_chains[0], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t)&initial_chains[1], + [NF_BR_POST_ROUTING] = (__nf_kptr_t)&initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3e907725529b..f1070fed4541 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -93,9 +93,9 @@ static inline int ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb, struct xt_action_param *par) { - par->target = w->u.watcher; + par->target = (struct xt_target *)w->u.watcher; par->targinfo = w->data; - w->u.watcher->target(skb, par); + ((struct xt_target *)w->u.watcher)->target(skb, par); /* watchers don't give a verdict */ return 0; } @@ -104,9 +104,9 @@ static inline int ebt_do_match(struct ebt_entry_match *m, const struct sk_buff *skb, struct xt_action_param *par) { - par->match = m->u.match; + par->match = (struct xt_match *)m->u.match; par->matchinfo = m->data; - return !m->u.match->match(skb, par); + return !((struct xt_match *)m->u.match)->match(skb, par); }
static inline int @@ -243,12 +243,12 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb,
t = ebt_get_target_c(point); /* standard target */ - if (!t->u.target->target) + if (!((struct xt_target *)t->u.target)->target) verdict = ((struct ebt_standard_target *)t)->verdict; else { - acpar.target = t->u.target; + acpar.target = (struct xt_target *)t->u.target; acpar.targinfo = t->data; - verdict = t->u.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.target)->target(skb, &acpar); } if (verdict == EBT_ACCEPT) { read_unlock_bh(&table->lock); @@ -411,7 +411,7 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, } if (IS_ERR(match)) return PTR_ERR(match); - m->u.match = match; + m->u.match = (__nf_kptr_t)match;
par->match = match; par->matchinfo = m->data; @@ -448,7 +448,7 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, return -ENOENT; }
- w->u.watcher = watcher; + w->u.watcher = (__nf_kptr_t)watcher;
par->target = watcher; par->targinfo = w->data; @@ -625,7 +625,7 @@ ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i) return 1;
par.net = net; - par.match = m->u.match; + par.match = (struct xt_match *)m->u.match; par.matchinfo = m->data; par.family = NFPROTO_BRIDGE; if (par.match->destroy != NULL) @@ -643,7 +643,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, struct net *net, unsigned int * return 1;
par.net = net; - par.target = w->u.watcher; + par.target = (struct xt_target *)w->u.watcher; par.targinfo = w->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -668,7 +668,7 @@ ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt) t = ebt_get_target(e);
par.net = net; - par.target = t->u.target; + par.target = (struct xt_target *)t->u.target; par.targinfo = t->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -759,8 +759,8 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; }
- t->u.target = target; - if (t->u.target == &ebt_standard_target) { + t->u.target = (__nf_kptr_t)target; + if (((struct xt_target *)t->u.target) == &ebt_standard_target) { if (gap < sizeof(struct ebt_standard_target)) { ret = -EFAULT; goto cleanup_watchers; @@ -771,7 +771,7 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; } } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) { - module_put(t->u.target->me); + module_put(((struct xt_target *)t->u.target)->me); ret = -EFAULT; goto cleanup_watchers; } @@ -1190,7 +1190,7 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
if (input_table == NULL || (repl = input_table->table) == NULL || repl->entries == NULL || repl->entries_size == 0 || - repl->counters != NULL || input_table->private != NULL) + ((struct xt_target *)repl->counters) != NULL || input_table->private != NULL) return -EINVAL;
/* Don't add one table to multiple lists. */ @@ -1457,18 +1457,18 @@ static inline int ebt_match_to_user(const struct ebt_entry_match *m, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)m - base), - m->u.match->name, m->data, sizeof(*m), - m->u.match->usersize, m->match_size, - m->u.match->revision); + ((struct xt_match *)m->u.match)->name, m->data, sizeof(*m), + ((struct xt_match *)m->u.match)->usersize, m->match_size, + ((struct xt_match *)m->u.match)->revision); }
static inline int ebt_watcher_to_user(const struct ebt_entry_watcher *w, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)w - base), - w->u.watcher->name, w->data, sizeof(*w), - w->u.watcher->usersize, w->watcher_size, - w->u.watcher->revision); + ((struct xt_target *)w->u.watcher)->name, w->data, sizeof(*w), + ((struct xt_target *)w->u.watcher)->usersize, w->watcher_size, + ((struct xt_target *)w->u.watcher)->revision); }
static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, @@ -1498,9 +1498,9 @@ static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, ret = EBT_WATCHER_ITERATE(e, ebt_watcher_to_user, base, ubase); if (ret != 0) return ret; - ret = ebt_obj_to_user(hlp, t->u.target->name, t->data, sizeof(*t), - t->u.target->usersize, t->target_size, - t->u.target->revision); + ret = ebt_obj_to_user(hlp, ((struct xt_target *)t->u.target)->name, t->data, sizeof(*t), + ((struct xt_target *)t->u.target)->usersize, t->target_size, + ((struct xt_target *)t->u.target)->revision); if (ret != 0) return ret;
@@ -1556,7 +1556,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user, entries_size = t->table->entries_size; nentries = t->table->nentries; entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp))) @@ -1641,7 +1641,7 @@ static int compat_match_to_user(struct ebt_entry_match *m, #endif unsigned int *size) { - const struct xt_match *match = m->u.match; + const struct xt_match *match = (struct xt_match *)m->u.match; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = ebt_compat_match_offset(match, m->match_size); compat_uint_t msize = m->match_size - off; @@ -1677,7 +1677,7 @@ static int compat_target_to_user(struct ebt_entry_target *t, #endif unsigned int *size) { - const struct xt_target *target = t->u.target; + const struct xt_target *target = (struct xt_target *)t->u.target; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = xt_compat_target_offset(target); compat_uint_t tsize = t->target_size - off; @@ -1780,14 +1780,14 @@ static int compat_copy_entry_to_user(struct ebt_entry *e,
static int compat_calc_match(struct ebt_entry_match *m, int *off) { - *off += ebt_compat_match_offset(m->u.match, m->match_size); + *off += ebt_compat_match_offset((struct xt_match *)m->u.match, m->match_size); *off += ebt_compat_entry_padsize(); return 0; }
static int compat_calc_watcher(struct ebt_entry_watcher *w, int *off) { - *off += xt_compat_target_offset(w->u.watcher); + *off += xt_compat_target_offset((struct xt_target *)w->u.watcher); *off += ebt_compat_entry_padsize(); return 0; } @@ -1812,7 +1812,7 @@ static int compat_calc_entry(const struct ebt_entry *e,
t = ebt_get_target_c(e);
- off += xt_compat_target_offset(t->u.target); + off += xt_compat_target_offset((struct xt_target *)t->u.target); off += ebt_compat_entry_padsize();
newinfo->entries_size -= off; @@ -1882,7 +1882,7 @@ static int compat_copy_everything_to_user(struct ebt_table *t, tinfo.entries_size = t->table->entries_size; tinfo.nentries = t->table->nentries; tinfo.entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp)))
In order to have the __nf_kptr_t type included, we need to move xtables.h include into the headers rather than the c files.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/uapi/linux/netfilter/xt_bpf.h | 1 + include/uapi/linux/netfilter/xt_statistic.h | 1 + net/netfilter/xt_bpf.c | 1 - net/netfilter/xt_statistic.c | 1 - 4 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h index f283619a6fef..7d666ac1336e 100644 --- a/include/uapi/linux/netfilter/xt_bpf.h +++ b/include/uapi/linux/netfilter/xt_bpf.h @@ -5,6 +5,7 @@ #include <linux/filter.h> #include <linux/limits.h> #include <linux/types.h> +#include <linux/netfilter/x_tables.h>
#define XT_BPF_MAX_NUM_INSTR 64 #define XT_BPF_PATH_MAX (XT_BPF_MAX_NUM_INSTR * sizeof(struct sock_filter)) diff --git a/include/uapi/linux/netfilter/xt_statistic.h b/include/uapi/linux/netfilter/xt_statistic.h index 330c1d28edd2..3ca611b011cb 100644 --- a/include/uapi/linux/netfilter/xt_statistic.h +++ b/include/uapi/linux/netfilter/xt_statistic.h @@ -2,6 +2,7 @@ #ifndef _XT_STATISTIC_H #define _XT_STATISTIC_H
+#include <linux/netfilter/x_tables.h> #include <linux/types.h>
enum xt_statistic_mode { diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 132465585cff..791f21554db2 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c @@ -13,7 +13,6 @@ #include <linux/bpf.h>
#include <linux/netfilter/xt_bpf.h> -#include <linux/netfilter/x_tables.h>
MODULE_AUTHOR("Willem de Bruijn willemb@google.com"); MODULE_DESCRIPTION("Xtables: BPF filter match"); diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index ae9cfc206604..a69cdbac4dc1 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c @@ -12,7 +12,6 @@ #include <linux/slab.h>
#include <linux/netfilter/xt_statistic.h> -#include <linux/netfilter/x_tables.h> #include <linux/module.h>
struct xt_statistic_priv {
On 11/10/2024 17:31, Joshua Lant wrote:
Changes from v2:
- [01/17] Updated first commit comment to make more sense to the reader.
- [XX/17] Numerous formatting nits fixed.
- [05/17] Fixed up local assignment and functional regression found.
- [08/17] Fixed up functional regression found.
Requested changes not addressed:
In patch [01/17]:
Do we really have to duplicate the typedefs here? There are already quite a few headers including <linux/netfilter.h> under include/uapi/linux/netfilter/ so including it in x_tables.h too shouldn't be too problematic.
Unfortunately this duplication is required. I encountered many issues building when I tried this initially before the last patch submission. Presumably this is an artefact of xtables being deprecated by nftables? Many definitions are duplicated between these two headers.
Could you elaborate on exactly what the errors are/what is duplicated? I don't see any issue building the kernel when including <linux/netfilter.h> in include/uapi/linux/netfilter/x_tables.h but I suppose there could be trouble when building userspace.
Many thanks,
Josh
Joshua Lant (17): netfilter: Create new type for kernel pointers. 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 xtables: move include to headers
I have tried applying those patches. Regardless of the ABI, I've found that the xt_IDLETIMER patch doesn't build - that's easily fixed. What is much more problematic is that building them in purecap generates a huge stream of warnings, for instance (showing up as an error here as I use -Werror):
kernel/private/arm/net/ipv4/netfilter/ip_tables.c:291:22: error: the following conversion will result in a CToPtr operation; the behaviour of CToPtr can be confusing since using CToPtr on an untagged capability will give 0 instead of the integer value and should therefore be explicitly annotated [-Werror,-Wcheri-pointer-conversion] acpar.match = (const struct xt_match *)ematch->u.kernel.match; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is because casting uintcap_t to an (integer) pointer in hybrid is considered ambiguous by the compiler - does the uintcap_t value represent a capability, and do you wish to extract its address? That's not the case here and the cast is harmless, but we can't easily disable the warning. The standard way to suppress it would be to cast to ptraddr_t first, but this gets really cumbersome (there are dozens of such casts in this series):
acpar.match = (const struct xt_match *)(ptraddr_t)ematch->u.kernel.match;
This made me realise that we can take a different approach, which involves some union magic but has the huge advantage of requiring no code change whatsoever besides headers. Let's take the example of this struct:
struct xt_entry_match { union { struct { ... } user; struct { __u16 match_size;
/* Used inside the kernel */ struct xt_match *match; } kernel;
/* Total length */ __u16 match_size; } u;
unsigned char data[]; };
What we want to ensure is that the "kernel" union member has the same size regardless of the kernel ABI. We do *not* actually need its "match" member to be consistent between the kernel and userspace, because only the kernel ever uses it. So what we could do is this:
struct xt_entry_match { union { struct { ... } user; struct { __u16 match_size;
/* Used inside the kernel */ union { struct xt_match *match; __nf_kptr_t __match; }; } kernel;
/* Total length */ __u16 match_size; } u;
unsigned char data[]; };
The anonymous union enables us to keep "match" unchanged while ensuring that both sides agree on the size and layout of the overall struct (this is the only purpose of the __match member, it is never directly used).
I believe that this trick works for all the uapi structs involved in this series. There is one exception, struct ebt_replace_kernel, which stores an array of kernel pointers. I doubt that this struct is ever manipulated from userspace though (i.e. its inclusion in a uapi header is probably a mistake), so leaving it unchanged should be safe.
I am frankly embarrassed to be suggesting another comprehensive change for that series, I should have realised earlier that this is the right approach to ensure that struct layouts are stable without a huge amount of churn. I'm happy to be posting a new version with that approach if you would prefer, I'd just ask you to do another round of testing.
Kevin
include/linux/netfilter.h | 6 + include/uapi/linux/netfilter.h | 8 + include/uapi/linux/netfilter/x_tables.h | 12 +- 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 | 7 +- 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 | 4 +- .../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 ++++---- 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 | 143 ++++++++++-------- net/netfilter/xt_RATEEST.c | 12 +- net/netfilter/xt_TCPMSS.c | 2 +- net/netfilter/xt_TEE.c | 12 +- net/netfilter/xt_bpf.c | 19 +-- 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 | 13 +- 37 files changed, 327 insertions(+), 267 deletions(-)
Hi Kevin,
Could you elaborate on exactly what the errors are/what is duplicated? I don't see any issue building the kernel when including <linux/netfilter.h> in include/uapi/linux/netfilter/x_tables.h but I suppose there could be trouble when building userspace.
I cannot remember off-hand what exactly what was giving me grief, but it was indeed when trying to compile iptables. IIRC I originally tried fixing up the iptables code to cope with this scenario you describe, including one header in the other, but I could not get it to work so had to duplicate the declaration in both headers...
I have tried applying those patches. Regardless of the ABI, I've found that the xt_IDLETIMER patch doesn't build - that's easily fixed. What is
Interesting, I wonder if this is an artefact of the version of the xt_IDLETIMER patch you aplpied. If you notice on the v2 patches I messed up one of the commits (xt_IDLETIMER), and then made a v3 revision of the xt_IDLETIMER patch. But then named this whole patch series v3 rather than v4 as I thought that would be even more confusing... https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... I wonder if that has anything to do with it?
much more problematic is that building them in purecap generates a huge stream of warnings, for instance (showing up as an error here as I use -Werror):
Sorry yeah I have removed -Werror from my build...
I am frankly embarrassed to be suggesting another comprehensive change for that series, I should have realised earlier that this is the right approach to ensure that struct layouts are stable without a huge amount of churn. I'm happy to be posting a new version with that approach if you would prefer, I'd just ask you to do another round of testing.
Kevin
Don't worry about it. You say jump, I say how high ahahaha. I will make the changes. It feels very much like this is my cross to bear... I will hopefully have some time to do this at some point next week. Thanks again for your input. Let's hope that this is the last of this :P
Cheers,
Josh
On 06/11/2024 11:28, Joshua Lant wrote:
Hi Kevin,
Could you elaborate on exactly what the errors are/what is duplicated? I don't see any issue building the kernel when including <linux/netfilter.h> in include/uapi/linux/netfilter/x_tables.h but I suppose there could be trouble when building userspace.
I cannot remember off-hand what exactly what was giving me grief, but it was indeed when trying to compile iptables. IIRC I originally tried fixing up the iptables code to cope with this scenario you describe, including one header in the other, but I could not get it to work so had to duplicate the declaration in both headers...
Fair enough, I trust that you tried your best - let's keep that duplication to avoid creating further headaches.
I have tried applying those patches. Regardless of the ABI, I've found that the xt_IDLETIMER patch doesn't build - that's easily fixed. What is
Interesting, I wonder if this is an artefact of the version of the xt_IDLETIMER patch you aplpied. If you notice on the v2 patches I messed up one of the commits (xt_IDLETIMER), and then made a v3 revision of the xt_IDLETIMER patch. But then named this whole patch series v3 rather than v4 as I thought that would be even more confusing... https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... I wonder if that has anything to do with it?
I don't think so, in fact the patch you sent as a follow-up to v2 should build fine, the issue is with the patch in this series. This hunk for instance:
@@ -136,48 +136,50 @@ static int idletimer_check_sysfs_name(const char *name, unsigned int size) static int idletimer_tg_create(struct idletimer_tg_info *info) { int ret; + struct idletimer_tg *timer; - info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL);
This won't build since info->timer is an integer (__nf_kptr_t) and kzalloc() returns a pointer. Either way all these complications should disappear with the new approach.
much more problematic is that building them in purecap generates a huge stream of warnings, for instance (showing up as an error here as I use -Werror):
Sorry yeah I have removed -Werror from my build...
Can't really blame you as this isn't enabled by default, I'd argue it should be but that is a separate topic :)
I am frankly embarrassed to be suggesting another comprehensive change for that series, I should have realised earlier that this is the right approach to ensure that struct layouts are stable without a huge amount of churn. I'm happy to be posting a new version with that approach if you would prefer, I'd just ask you to do another round of testing.
Kevin
Don't worry about it. You say jump, I say how high ahahaha. I will make the changes. It feels very much like this is my cross to bear... I will hopefully have some time to do this at some point next week. Thanks again for your input. Let's hope that this is the last of this :P
I very much hope so as well... I really appreciate your patience once again!
Feel free to reorganise patches as you see fit (it might not be necessary to have one patch per header since the changes become much smaller, but this is really up to you). One more note: in patch 10, struct xt_hashlimit_info already has a union "u" for the ptr and master pointers, so there's no need to nest another union inside - just add an __nf_kptr_t member inside "u".
Kevin
linux-morello@op-lists.linaro.org