This is v2 of the previous patchset found here:
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/...
I have added the new __nf_kptr_t type and modified all the patches accordingly, as well as fixing up all (hopefully) of the nits found in the previous patches.
Many thanks Kevin for your input on everything. I hope that this is now in a decent state.
Cheers.
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 | 139 +++++++++--------- 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, 323 insertions(+), 267 deletions(-)
In order to fix alignment between kernel and userspace structs in UAPI headers, create a new type which will provide space for a user pointer in the struct. This is required in order not to break the existing fix in the event that a fully purecap kernel is created. As it stands, the purecap kernel would break the uapi structs since only 8B is ever given in the field for the kernel pointers in the uapi structs, due to the use of unsigned long in those fields. Make nonPCuABI use this unsigned long, but the PCuABI should use a capability. This means both hybrid mode and a purecap kernel would work in both instances.
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..58fd97995e23 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..bd8542cb9a41 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 {
On 02/09/2024 17:02, Joshua Lant wrote:
In order to fix alignment between kernel and userspace structs in UAPI headers, create a new type which will provide space for a user pointer in the struct. This is required in order not to break the existing fix in the event that a fully purecap kernel is created. As it stands, the purecap kernel would break the uapi structs since only 8B is ever given in the field for the kernel pointers in the uapi structs, due to the use of unsigned long in those fields. Make nonPCuABI use this unsigned long, but the PCuABI should use a capability. This means both hybrid mode and a purecap kernel would work in both instances.
This is pretty hard to parse for someone lacking further context. The two most important points to make are: 1. we need a type that is the same size from the perspective of both the kernel and userspace, and 2. we need this type to be able to hold a kernel pointer, regardless of the kernel ABI. 1. justifies not using a pointer type (kernel and userspace won't agree in the hybrid model), and 2. justifies making the type a capability, in case the kernel wants its pointers to be capabilities. Worth spelling out that this is unnecessary in the hybrid model, it is only done to guarantee that the uapi remains stable.
A few more things: there is no "existing fix" (considering this patch is applied first, at which point the netfilter interface is unmodified), and there is no "user pointer" involved here.
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..58fd97995e23 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;
Nit: careful with tabs/spaces, there's currently a strange mix across the typedefs. There's typically no tab after "typedef", while alignment (if desired) of the type name is achieved with tabs only.
+#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..bd8542cb9a41 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
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.
Similarly each patch adding a reference to __nf_kptr_t to a uapi header should include <linux/netfilter.h> if needed (removing the need for patch 17).
Kevin
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..f972bd914718 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..ef2273702e11 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;
On 02/09/2024 17:02, Joshua Lant wrote:
@@ -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;
Nit: still a few unnecessary spaces between cast and variable in various places.
Kevin
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..dfcf7ae5c090 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 f972bd914718..e3e27464fa7d 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 ef2273702e11..ee301e638980 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..91e3e919dbb2 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 | 139 ++++++++++---------- 2 files changed, 77 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..7140e45b65bd 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -136,8 +136,9 @@ 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_local = (struct idletimer_tg *)info->timer;
- info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = (__nf_kptr_t) kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; @@ -148,36 +149,36 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) goto out_free_timer;
sysfs_attr_init(&info->timer->attr.attr); - info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); - if (!info->timer->attr.attr.name) { + (timer_localinfo->timer)->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!timer_local->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + timer_local->attr.attr.mode = 0444; + timer_local->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &timer_local->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_local->entry, &idletimer_tg_list);
- timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - info->timer->refcnt = 1; + timer_setup(&timer_local->timer, idletimer_tg_expired, 0); + timer_local->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&timer_local->work, idletimer_tg_work);
- mod_timer(&info->timer->timer, + mod_timer(&timer_local->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(timer_local->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(timer_local); out: return ret; } @@ -185,8 +186,9 @@ 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_local = (struct idletimer_tg *)info->timer;
- info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = (__nf_kptr_t) kmalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out; @@ -196,16 +198,16 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) if (ret < 0) goto out_free_timer;
- sysfs_attr_init(&info->timer->attr.attr); - info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); - if (!info->timer->attr.attr.name) { + sysfs_attr_init(&timer_local->attr.attr); + timer_local->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!timer_local->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; } - info->timer->attr.attr.mode = 0444; - info->timer->attr.show = idletimer_tg_show; + timer_local->attr.attr.mode = 0444; + timer_local->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); + ret = sysfs_create_file(idletimer_tg_kobj, &timer_local->attr.attr); if (ret < 0) { pr_debug("couldn't add file to sysfs"); goto out_free_attr; @@ -214,32 +216,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_local->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_local->timer_type = info->timer_type; + timer_local->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work); + INIT_WORK(&timer_local->work, idletimer_tg_work);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + if (timer_local->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout; - alarm_init(&info->timer->alarm, ALARM_BOOTTIME, + alarm_init(&timer_local->alarm, ALARM_BOOTTIME, idletimer_tg_alarmproc); - info->timer->alarm.data = info->timer; + timer_local->alarm.data = timer_local; tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&timer_local->alarm, tout); } else { - timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - mod_timer(&info->timer->timer, + timer_setup(&timer_local->timer, idletimer_tg_expired, 0); + mod_timer(&timer_local->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
return 0;
out_free_attr: - kfree(info->timer->attr.attr.name); + kfree(timer_local->attr.attr.name); out_free_timer: - kfree(info->timer); + kfree(timer_local); out: return ret; } @@ -255,7 +257,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 +270,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_local = (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_local->timer_type & XT_IDLETIMER_ALARM) { ktime_t tout = ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + alarm_start_relative(&timer_local->alarm, tout); } else { - mod_timer(&info->timer->timer, + mod_timer(&timer_local->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies); }
@@ -307,6 +310,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_local = (struct idletimer_tg *)info->timer;
pr_debug("checkentry targinfo%s\n", info->label);
@@ -318,14 +322,14 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) } mutex_lock(&list_mutex);
- info->timer = __idletimer_tg_find_by_label(info->label); - if (info->timer) { - info->timer->refcnt++; - mod_timer(&info->timer->timer, + info->timer = (__nf_kptr_t) __idletimer_tg_find_by_label(info->label); + if (timer_local) { + timer_local->refcnt++; + mod_timer(&timer_local->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_local->refcnt); } else { ret = idletimer_tg_create(info); if (ret < 0) { @@ -343,6 +347,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_local = (struct idletimer_tg *)info->timer;
pr_debug("checkentry targinfo%s\n", info->label);
@@ -363,31 +368,31 @@ static int idletimer_tg_checkentry_v1(const struct xt_tgchk_param *par)
mutex_lock(&list_mutex);
- info->timer = __idletimer_tg_find_by_label(info->label); + info->timer = (__nf_kptr_t) __idletimer_tg_find_by_label(info->label); if (info->timer) { - if (info->timer->timer_type != info->timer_type) { + if (timer_local->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_local->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_local->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_local->alarm, tout); } } else { - mod_timer(&info->timer->timer, + mod_timer(&timer_local->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_local->refcnt); } else { ret = idletimer_tg_create_v1(info); if (ret < 0) { @@ -404,23 +409,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_local = (struct idletimer_tg *)info->timer;
pr_debug("destroy targinfo %s\n", info->label);
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--timer_local->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_local->entry); + timer_shutdown_sync(&timer_local->timer); + cancel_work_sync(&timer_local->work); + sysfs_remove_file(idletimer_tg_kobj, &timer_local->attr.attr); + kfree(timer_local->attr.attr.name); + kfree(timer_local); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, timer_local->refcnt); }
mutex_unlock(&list_mutex); @@ -429,27 +435,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_local = (struct idletimer_tg *)info->timer;
pr_debug("destroy targinfo %s\n", info->label);
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) { + if (--timer_local->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_local->entry); + if (timer_local->timer_type & XT_IDLETIMER_ALARM) { + alarm_cancel(&timer_local->alarm); } else { - timer_shutdown_sync(&info->timer->timer); + timer_shutdown_sync(&timer_local->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_local->work); + sysfs_remove_file(idletimer_tg_kobj, &timer_local->attr.attr); + kfree(timer_local->attr.attr.name); + kfree(timer_local); } else { pr_debug("decreased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); + info->label, timer_local->refcnt); }
mutex_unlock(&list_mutex);
On 02/09/2024 17:02, Joshua Lant wrote:
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index db720efa811d..7140e45b65bd 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -136,8 +136,9 @@ 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_local = (struct idletimer_tg *)info->timer;
Such assignment does not make sense in those functions where info->timer is an output, not an input: info->timer is initialised on the next line. As a result timer_local will be set to an irrelevant value.
The most sensible option is probably to replace all references to info->timer with timer_local (including on the next line), and set info->timer to timer_local once the latter is (successfully) initialised.
Also a general nit: local variables are not normally named to indicate they are local. In other words, just "timer" instead of "timer_local" would do just fine.
Kevin
- info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL);
- info->timer = (__nf_kptr_t) kzalloc(sizeof(struct idletimer_tg), GFP_KERNEL); if (!info->timer) { ret = -ENOMEM; goto out;
@@ -148,36 +149,36 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) goto out_free_timer; sysfs_attr_init(&info->timer->attr.attr);
- info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
- if (!info->timer->attr.attr.name) {
- (timer_localinfo->timer)->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
- if (!timer_local->attr.attr.name) { ret = -ENOMEM; goto out_free_timer; }
- info->timer->attr.attr.mode = 0444;
- info->timer->attr.show = idletimer_tg_show;
- timer_local->attr.attr.mode = 0444;
- timer_local->attr.show = idletimer_tg_show;
- ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr);
- ret = sysfs_create_file(idletimer_tg_kobj, &timer_local->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_local->entry, &idletimer_tg_list);
- timer_setup(&info->timer->timer, idletimer_tg_expired, 0);
- info->timer->refcnt = 1;
- timer_setup(&timer_local->timer, idletimer_tg_expired, 0);
- timer_local->refcnt = 1;
- INIT_WORK(&info->timer->work, idletimer_tg_work);
- INIT_WORK(&timer_local->work, idletimer_tg_work);
- mod_timer(&info->timer->timer,
- mod_timer(&timer_local->timer, msecs_to_jiffies(info->timeout * 1000) + jiffies);
return 0; out_free_attr:
- kfree(info->timer->attr.attr.name);
- kfree(timer_local->attr.attr.name);
out_free_timer:
- kfree(info->timer);
- kfree(timer_local);
out: return ret; }
[...]
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..114415c85f72 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..8d5f27337595 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..0cb3cd1d3d87 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 02/09/2024 17:02, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __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..0cb3cd1d3d87 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);
Nit: no need for parentheses around the whole expression (same throughout this file).
return __bpf_mt_check_bytecode(info->bpf_program, info->bpf_program_num_elem,
&info->filter);
&filter);
I've just realised that this change is not equivalent: the last argument of that function is struct bpf_prog **ret, and as the name suggests it is an output argument, i.e. the function will write to that pointer. This change will result in the local variable filter being written to, but not info->filter.
The least invasive option is probably to make filter itself a pointer to info->filter:
struct bpf_prog **filter = &(struct bpf_prog *)info->filter;
Kevin
} 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);
else if (info->mode == XT_BPF_MODE_FD_ELF)&filter);
return __bpf_mt_check_fd(info->fd, &info->filter);
else if (info->mode == XT_BPF_MODE_PATH_PINNED)return __bpf_mt_check_fd(info->fd, &filter);
return __bpf_mt_check_path(info->path, &info->filter);
else return -EINVAL;return __bpf_mt_check_path(info->path, &filter);
} @@ -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..be464a16b96b 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..05794305da1d 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 02/09/2024 17:02, Joshua Lant wrote:
On morello architecture, use of kernel pointers in the uapi structures is not permitted, due to different alignment requirements. Modify these to be __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..05794305da1d 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 **/
Nit: still a space missing before */ (here and comments below).
Kevin
- __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;
} u;__nf_kptr_t master;
}; @@ -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..f4ae4f22af14 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..693ff0ab3eca 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..f125102bc3c3 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..2cf4dbcbc754 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..a0e859c694cf 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..39b88a2dd9d5 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -31,7 +31,7 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = 1 << NF_BR_BROUTING, .entries_size = sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_BROUTING] = &initial_chain, + [NF_BR_BROUTING] = (__nf_kptr_t) &initial_chain, }, .entries = (char *)&initial_chain, }; diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index dacd81b12e62..c0394b3bd68e 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = FILTER_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_LOCAL_IN] = &initial_chains[0], - [NF_BR_FORWARD] = &initial_chains[1], - [NF_BR_LOCAL_OUT] = &initial_chains[2], + [NF_BR_LOCAL_IN] = (__nf_kptr_t) &initial_chains[0], + [NF_BR_FORWARD] = (__nf_kptr_t) &initial_chains[1], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t) &initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 0f2a8c6118d4..da9a907e5b2d 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -36,9 +36,9 @@ static struct ebt_replace_kernel initial_table = { .valid_hooks = NAT_VALID_HOOKS, .entries_size = 3 * sizeof(struct ebt_entries), .hook_entry = { - [NF_BR_PRE_ROUTING] = &initial_chains[0], - [NF_BR_LOCAL_OUT] = &initial_chains[1], - [NF_BR_POST_ROUTING] = &initial_chains[2], + [NF_BR_PRE_ROUTING] = (__nf_kptr_t) &initial_chains[0], + [NF_BR_LOCAL_OUT] = (__nf_kptr_t) &initial_chains[1], + [NF_BR_POST_ROUTING] = (__nf_kptr_t) &initial_chains[2], }, .entries = (char *)initial_chains, }; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3e907725529b..a06a4c8bf6f6 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -93,9 +93,9 @@ static inline int ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb, struct xt_action_param *par) { - par->target = w->u.watcher; + par->target = (struct xt_target *)w->u.watcher; par->targinfo = w->data; - w->u.watcher->target(skb, par); + ((struct xt_target *)w->u.watcher)->target(skb, par); /* watchers don't give a verdict */ return 0; } @@ -104,9 +104,9 @@ static inline int ebt_do_match(struct ebt_entry_match *m, const struct sk_buff *skb, struct xt_action_param *par) { - par->match = m->u.match; + par->match = (struct xt_match *)m->u.match; par->matchinfo = m->data; - return !m->u.match->match(skb, par); + return !((struct xt_match *)m->u.match)->match(skb, par); }
static inline int @@ -243,12 +243,12 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb,
t = ebt_get_target_c(point); /* standard target */ - if (!t->u.target->target) + if (!((struct xt_target *)t->u.target)->target) verdict = ((struct ebt_standard_target *)t)->verdict; else { - acpar.target = t->u.target; + acpar.target = (struct xt_target *)t->u.target; acpar.targinfo = t->data; - verdict = t->u.target->target(skb, &acpar); + verdict = ((struct xt_target *)t->u.target)->target(skb, &acpar); } if (verdict == EBT_ACCEPT) { read_unlock_bh(&table->lock); @@ -411,7 +411,7 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, } if (IS_ERR(match)) return PTR_ERR(match); - m->u.match = match; + m->u.match = (__nf_kptr_t) match;
par->match = match; par->matchinfo = m->data; @@ -448,7 +448,7 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, return -ENOENT; }
- w->u.watcher = watcher; + w->u.watcher = (__nf_kptr_t) watcher;
par->target = watcher; par->targinfo = w->data; @@ -625,7 +625,7 @@ ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i) return 1;
par.net = net; - par.match = m->u.match; + par.match = (struct xt_match *)m->u.match; par.matchinfo = m->data; par.family = NFPROTO_BRIDGE; if (par.match->destroy != NULL) @@ -643,7 +643,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, struct net *net, unsigned int * return 1;
par.net = net; - par.target = w->u.watcher; + par.target = (struct xt_target *)w->u.watcher; par.targinfo = w->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -668,7 +668,7 @@ ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt) t = ebt_get_target(e);
par.net = net; - par.target = t->u.target; + par.target = (struct xt_target *)t->u.target; par.targinfo = t->data; par.family = NFPROTO_BRIDGE; if (par.target->destroy != NULL) @@ -759,8 +759,8 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; }
- t->u.target = target; - if (t->u.target == &ebt_standard_target) { + t->u.target = (__nf_kptr_t) target; + if (((struct xt_target *)t->u.target) == &ebt_standard_target) { if (gap < sizeof(struct ebt_standard_target)) { ret = -EFAULT; goto cleanup_watchers; @@ -771,7 +771,7 @@ ebt_check_entry(struct ebt_entry *e, struct net *net, goto cleanup_watchers; } } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) { - module_put(t->u.target->me); + module_put(((struct xt_target *)t->u.target)->me); ret = -EFAULT; goto cleanup_watchers; } @@ -1190,7 +1190,7 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
if (input_table == NULL || (repl = input_table->table) == NULL || repl->entries == NULL || repl->entries_size == 0 || - repl->counters != NULL || input_table->private != NULL) + ((struct xt_target *)repl->counters) != NULL || input_table->private != NULL) return -EINVAL;
/* Don't add one table to multiple lists. */ @@ -1457,18 +1457,18 @@ static inline int ebt_match_to_user(const struct ebt_entry_match *m, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)m - base), - m->u.match->name, m->data, sizeof(*m), - m->u.match->usersize, m->match_size, - m->u.match->revision); + ((struct xt_match *)m->u.match)->name, m->data, sizeof(*m), + ((struct xt_match *)m->u.match)->usersize, m->match_size, + ((struct xt_match *)m->u.match)->revision); }
static inline int ebt_watcher_to_user(const struct ebt_entry_watcher *w, const char *base, char __user *ubase) { return ebt_obj_to_user(ubase + ((char *)w - base), - w->u.watcher->name, w->data, sizeof(*w), - w->u.watcher->usersize, w->watcher_size, - w->u.watcher->revision); + ((struct xt_target *)w->u.watcher)->name, w->data, sizeof(*w), + ((struct xt_target *)w->u.watcher)->usersize, w->watcher_size, + ((struct xt_target *)w->u.watcher)->revision); }
static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, @@ -1498,9 +1498,9 @@ static inline int ebt_entry_to_user(struct ebt_entry *e, const char *base, ret = EBT_WATCHER_ITERATE(e, ebt_watcher_to_user, base, ubase); if (ret != 0) return ret; - ret = ebt_obj_to_user(hlp, t->u.target->name, t->data, sizeof(*t), - t->u.target->usersize, t->target_size, - t->u.target->revision); + ret = ebt_obj_to_user(hlp, ((struct xt_target *)t->u.target)->name, t->data, sizeof(*t), + ((struct xt_target *)t->u.target)->usersize, t->target_size, + ((struct xt_target *)t->u.target)->revision); if (ret != 0) return ret;
@@ -1556,7 +1556,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user, entries_size = t->table->entries_size; nentries = t->table->nentries; entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp))) @@ -1641,7 +1641,7 @@ static int compat_match_to_user(struct ebt_entry_match *m, #endif unsigned int *size) { - const struct xt_match *match = m->u.match; + const struct xt_match *match = (struct xt_match *)m->u.match; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = ebt_compat_match_offset(match, m->match_size); compat_uint_t msize = m->match_size - off; @@ -1677,7 +1677,7 @@ static int compat_target_to_user(struct ebt_entry_target *t, #endif unsigned int *size) { - const struct xt_target *target = t->u.target; + const struct xt_target *target = (struct xt_target *)t->u.target; struct compat_ebt_entry_mwt __user *cm = *dstptr; int off = xt_compat_target_offset(target); compat_uint_t tsize = t->target_size - off; @@ -1780,14 +1780,14 @@ static int compat_copy_entry_to_user(struct ebt_entry *e,
static int compat_calc_match(struct ebt_entry_match *m, int *off) { - *off += ebt_compat_match_offset(m->u.match, m->match_size); + *off += ebt_compat_match_offset((struct xt_match *)m->u.match, m->match_size); *off += ebt_compat_entry_padsize(); return 0; }
static int compat_calc_watcher(struct ebt_entry_watcher *w, int *off) { - *off += xt_compat_target_offset(w->u.watcher); + *off += xt_compat_target_offset((struct xt_target *)w->u.watcher); *off += ebt_compat_entry_padsize(); return 0; } @@ -1812,7 +1812,7 @@ static int compat_calc_entry(const struct ebt_entry *e,
t = ebt_get_target_c(e);
- off += xt_compat_target_offset(t->u.target); + off += xt_compat_target_offset((struct xt_target *)t->u.target); off += ebt_compat_entry_padsize();
newinfo->entries_size -= off; @@ -1882,7 +1882,7 @@ static int compat_copy_everything_to_user(struct ebt_table *t, tinfo.entries_size = t->table->entries_size; tinfo.nentries = t->table->nentries; tinfo.entries = t->table->entries; - oldcounters = t->table->counters; + oldcounters = (struct ebt_counter *)t->table->counters; }
if (copy_from_user(&tmp, user, sizeof(tmp)))
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 0cb3cd1d3d87..4101130dc899 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 a0e859c694cf..c5a9056bfd63 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 02/09/2024 17:02, Joshua Lant wrote:
This is v2 of the previous patchset found here:
https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/...
I have added the new __nf_kptr_t type and modified all the patches accordingly, as well as fixing up all (hopefully) of the nits found in the previous patches.
Many thanks Kevin for your input on everything. I hope that this is now in a decent state.
Thank you for taking the time to rework this series!
Overall this is looking good to me, there are a few issues here and there (see inline replies) but I expect the next version will be in good shape to merge. Something I'd like to check before that is how you are testing these changes? I am a little concerned that patch 5 and 8 introduce clear functional regressions that presumably went unnoticed. These regressions should occur regardless of the ABI, so even netfilter tests built in the standard arm64 ABI should expose them. I see that a few netfilter kselftests exist, that may be a good start - building them for standard arm64 shouldn't be an issue (purecap is another story but this is less essential).
Kevin
Cheers.
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 | 139 +++++++++--------- 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, 323 insertions(+), 267 deletions(-)
Hi Kevin,
Sorry it has taken me so long to get an update on this...
Overall this is looking good to me, there are a few issues here and there (see inline replies) but I expect the next version will be in good shape to merge. Something I'd like to check before that is how you are testing these changes? I am a little concerned that patch 5 and 8 introduce clear functional regressions that presumably went unnoticed. These regressions should occur regardless of the ABI, so even netfilter tests built in the standard arm64 ABI should expose them. I see that a few netfilter kselftests exist, that may be a good start - building them for standard arm64 shouldn't be an issue (purecap is another story but this is less essential).
Kevin
My testing up to this point has been mainly on the set of 68 iptables tests (and prior to this testing using the libmnl and libnftnl tests to ensure that those packages were working correctly), testing the purecap versions of the libraries. Of these there are 3 failing tests. Two of these are due to minor issues with the diff of the expected output. One appears to be some problem setting up network namespaces that I have not had time to pursue. I am only testing the nftables tests, since I have not ported the legacy iptables.
I have got the patches ready for a V3 submission. I have been trying to get the kselftests working before submitting, but this is proving to be more of a pain than I'd imagined... The tests are running but are showing many strange errors in many places. There are problems for me getting these working in both purecap and non-purecap scenarios. The issue is that most of the tests utilize userspace packages such as iproute2, iputils and iptables, and require patching to work with updated headers.
purecap:
I have ported all of the above packages to purecap (in theory). However, some of these packages have been ported with caveats or potentially missing/broken functionality due to the need for expediency...
My primary goal in all this was to have WireGuard ported into purecap and working (passing all of it's tests). Since this is done, I have not worked further on these packages. One good exmaple of this is ping inside iputils package. It has a dependency on libgmp, which performs arbitrary precision arithmetic for some functionality. I did not want to waste my time porting this to purecap since it works for the tests that I need ping for. This could well be why many ping commands are failing in the tests, although i cannot be sure unless I spend time i dont have debugging.
non-purecap:
Building and including all of these userspace packages in non-purecap, but still using the updated kernel headers and the kselftests from kernel version 6.7 is itself non-trivial. The kselftests have many commits in the past year. My build system uses Yocto, and many of the default recipes use old package versions which may need updating and patching to newer versions in order to pass these newer tests. I have seen this in several instances in my travels getting iptables tests passing. Updating has then led to other problems which required further patching...
As an example, when fixing iptables I had issues updating the kernel headers in the iptables repo, since I could not point to a non-default header location using the configure.ac in its current state. See this thread:
https://marc.info/?l=netfilter-devel&m=172304132117451&w=2
Unfortunately I dont think I have time to go down any more rabbit holes with figuring out where the issues in these tests reside (actual failure or failure due to package versions/missing features)... I have not even managed to get the perl script that runs the kselftest suite working, since I have an error about the correct perl modules not being available...
tl;dr
I do not really have time to divert my energies into getting these kselftests working. I have been testing with the iptables suite. I will submit the v3 of the patches with the changes, and you can decide if they are sufficently safe for applying.
On 11/10/2024 17:04, Joshua Lant wrote:
Hi Kevin,
Sorry it has taken me so long to get an update on this...
No problem, my bandwidth is equally limited, doing what we can :)
Overall this is looking good to me, there are a few issues here and there (see inline replies) but I expect the next version will be in good shape to merge. Something I'd like to check before that is how you are testing these changes? I am a little concerned that patch 5 and 8 introduce clear functional regressions that presumably went unnoticed. These regressions should occur regardless of the ABI, so even netfilter tests built in the standard arm64 ABI should expose them. I see that a few netfilter kselftests exist, that may be a good start - building them for standard arm64 shouldn't be an issue (purecap is another story but this is less essential).
Kevin
My testing up to this point has been mainly on the set of 68 iptables tests (and prior to this testing using the libmnl and libnftnl tests to ensure that those packages were working correctly), testing the purecap versions of the libraries. Of these there are 3 failing tests. Two of these are due to minor issues with the diff of the expected output. One appears to be some problem setting up network namespaces that I have not had time to pursue. I am only testing the nftables tests, since I have not ported the legacy iptables.
I have got the patches ready for a V3 submission. I have been trying to get the kselftests working before submitting, but this is proving to be more of a pain than I'd imagined... The tests are running but are showing many strange errors in many places. There are problems for me getting these working in both purecap and non-purecap scenarios. The issue is that most of the tests utilize userspace packages such as iproute2, iputils and iptables, and require patching to work with updated headers.
purecap:
I have ported all of the above packages to purecap (in theory). However, some of these packages have been ported with caveats or potentially missing/broken functionality due to the need for expediency...
My primary goal in all this was to have WireGuard ported into purecap and working (passing all of it's tests). Since this is done, I have not worked further on these packages. One good exmaple of this is ping inside iputils package. It has a dependency on libgmp, which performs arbitrary precision arithmetic for some functionality. I did not want to waste my time porting this to purecap since it works for the tests that I need ping for. This could well be why many ping commands are failing in the tests, although i cannot be sure unless I spend time i dont have debugging.
This is understood - there are way too many dependencies for you to be able to test the changes comprehensively in purecap.
non-purecap:
Building and including all of these userspace packages in non-purecap, but still using the updated kernel headers and the kselftests from kernel version 6.7 is itself non-trivial. The kselftests have many commits in the past year. My build system uses Yocto, and many of the default recipes use old package versions which may need updating and patching to newer versions in order to pass these newer tests. I have seen this in several instances in my travels getting iptables tests passing. Updating has then led to other problems which required further patching...
As an example, when fixing iptables I had issues updating the kernel headers in the iptables repo, since I could not point to a non-default header location using the configure.ac in its current state. See this thread:
https://marc.info/?l=netfilter-devel&m=172304132117451&w=2
Unfortunately I dont think I have time to go down any more rabbit holes with figuring out where the issues in these tests reside (actual failure or failure due to package versions/missing features)... I have not even managed to get the perl script that runs the kselftest suite working, since I have an error about the correct perl modules not being available...
That's fair enough. I hoped that those kselftests would be reasonably easy to run, but that doesn't seem to be the case. Thanks for trying in any case. I've got a new idea that will make the changes a lot less invasive (will reply on v3), so comprehensive testing will be less essential.
Kevin
tl;dr
I do not really have time to divert my energies into getting these kselftests working. I have been testing with the iptables suite. I will submit the v3 of the patches with the changes, and you can decide if they are sufficently safe for applying.
linux-morello@op-lists.linaro.org