From 7297a8ef3cab3b0faf1426622ee902a2144e2e89 Mon Sep 17 00:00:00 2001 From: Thomas De Schampheleire Date: Wed, 24 Mar 2021 11:27:14 +0100 Subject: [PATCH] ebtables.h: restore KERNEL_64_USERSPACE_32 checks Commit e6359eedfbf497e52d52451072aea4713ed80a88 replaced the file ebtables.h but removed the usage of KERNEL_64_USERSPACE_32. This breaks boards where such flag is relevant, with following messages: [ 6364.971346] kernel msg: ebtables bug: please report to author: Standard target size too big Unable to update the kernel. Two possible causes: 1. Multiple ebtables programs were executing simultaneously. The ebtables userspace tool doesn't by default support multiple ebtables programs running concurrently. The ebtables option --concurrent or a tool like flock can be used to support concurrent scripts that update the ebtables kernel tables. 2. The kernel doesn't support a certain ebtables extension, consider recompiling your kernel or insmod the extension. Analysis shows that the structure 'ebt_replace' passed from userspace ebtables to the kernel, is too small, i.e 80 bytes instead of 120 in case of 64-bit kernel. Note that the ebtables build system seems to assume that 'sparc64' is the only case where KERNEL_64_USERSPACE_32 is relevant, but this is not true. This situation can happen on many architectures, especially in embedded systems. For example, an Aarch64 processor with kernel in 64-bit but userland build for 32-bit Arm. Or a 64-bit MIPS Octeon III processor, with userland running in the 'n32' ABI. Signed-off-by: Thomas De Schampheleire Upstream-Status: http://patchwork.ozlabs.org/project/netfilter-devel/patch/20210518181730.13436-1-patrickdepinguin@gmail.com/ --- include/linux/netfilter_bridge/ebtables.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 5be75f2..3c2b61e 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -49,12 +49,21 @@ struct ebt_replace { /* total size of the entries */ unsigned int entries_size; /* start of the chains */ +#ifdef KERNEL_64_USERSPACE_32 + uint64_t hook_entry[NF_BR_NUMHOOKS]; +#else struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; +#endif /* nr of counters userspace expects back */ unsigned int num_counters; /* where the kernel will put the old counters */ +#ifdef KERNEL_64_USERSPACE_32 + uint64_t counters; + uint64_t entries; +#else struct ebt_counter *counters; char *entries; +#endif }; struct ebt_replace_kernel { @@ -129,6 +138,9 @@ struct ebt_entry_match { } u; /* size of data */ unsigned int match_size; +#ifdef KERNEL_64_USERSPACE_32 + unsigned int pad; +#endif unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); }; @@ -142,6 +154,9 @@ struct ebt_entry_watcher { } u; /* size of data */ unsigned int watcher_size; +#ifdef KERNEL_64_USERSPACE_32 + unsigned int pad; +#endif unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); }; @@ -155,6 +170,9 @@ struct ebt_entry_target { } u; /* size of data */ unsigned int target_size; +#ifdef KERNEL_64_USERSPACE_32 + unsigned int pad; +#endif unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); }; @@ -162,6 +180,9 @@ struct ebt_entry_target { struct ebt_standard_target { struct ebt_entry_target target; int verdict; +#ifdef KERNEL_64_USERSPACE_32 + unsigned int pad; +#endif }; /* one entry */ -- 2.26.2