In the netfilter subsystem there are many structs inside the UAPI headers which contain kernel pointers. This causes misalignment between userspace and kernel space of these structures when using the PCuABI, due to the differing sizes of the pointer in kernel space, and the capability in userspace. This leads to issues with some netlink messages sent between user/kernel space.
In order to fix this, we require a new type which is the same size from the perspective of both the user and the kernel, and is able to hold a kernel pointer regardless of the ABI which is being used (non-purecap, hybrid pc-userspace/non-pc kernel, or a fully purecap kernel and userpsace).
In order to achieve this we create a new type which is the size of a capability when using CONFIG_CHERI_PURECAP_UABI, and the size of a pointer if not. We will then replace the kernel pointers in the UAPI structs with this new type. Doing this will maintain consistent struct sizing, even if a fully purecap kernel is used.
The drawback to this approach is that this method is unnecessary in the case where we have a purecap userspace and non-purecap kernel, since the kernel pointer in the structs are never actually touched by userspace, and so are not required to be the size of a capability. However, it is necessary to guarantee that the UAPI remains stable no matter what the kernel ABI uses.
The use of x_tables.h and netfilter.h appears to be mutually exclusive within the kernel.This is why it is required to add the new definition in both netfilter.h and x_tables.h. Since many conflicts between definitions exist when including netfilter.h in x_tables.h. This overlap is presumably is an artefact of xtables being superseded by nftables.
Signed-off-by: Joshua Lant joshualant@gmail.com --- include/linux/netfilter.h | 6 ++++++ include/uapi/linux/netfilter.h | 8 ++++++++ include/uapi/linux/netfilter/x_tables.h | 8 ++++++++ 3 files changed, 22 insertions(+)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 80900d910992..3041b4b78be9 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -17,6 +17,12 @@ #include <linux/sockptr.h> #include <net/net_namespace.h>
+#ifdef CONFIG_CHERI_PURECAP_UABI +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif + static inline int NF_DROP_GETERR(int verdict) { return -(verdict >> NF_VERDICT_QBITS); diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h index 5a79ccb76701..bb793b70d64c 100644 --- a/include/uapi/linux/netfilter.h +++ b/include/uapi/linux/netfilter.h @@ -7,6 +7,14 @@ #include <linux/in.h> #include <linux/in6.h>
+#ifndef __KERNEL__ +#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif +#endif + /* Responses from hook functions. */ #define NF_DROP 0 #define NF_ACCEPT 1 diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h index 796af83a963a..e695b6d34a6f 100644 --- a/include/uapi/linux/netfilter/x_tables.h +++ b/include/uapi/linux/netfilter/x_tables.h @@ -8,6 +8,14 @@ #define XT_EXTENSION_MAXNAMELEN 29 #define XT_TABLE_MAXNAMELEN 32
+#ifndef __KERNEL__ +#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t __nf_kptr_t; +#else +typedef unsigned long __nf_kptr_t; +#endif +#endif + struct xt_entry_match { union { struct {