When running a 64-bit kernel with a 32-bit iptables binary, the
size of the xt_nfacct_match_info struct diverges.
kernel: sizeof(struct xt_nfacct_match_info) : 40
iptables: sizeof(struct xt_nfacct_match_info)) : 36
This patch is the userspace fix of the memory misalignment.
It introduces a v1 ABI with the correct alignment and stays
compatible with unfixed revision 0 kernels.
Signed-off-by: Juliana Rodrigueiro <[email protected]>
---
Note to the maintainer:
Please feel free to adapt the commit message to your liking.
extensions/libxt_nfacct.c | 40 ++++++++++++++++++++---------
include/linux/netfilter/xt_nfacct.h | 5 ++++
2 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/extensions/libxt_nfacct.c b/extensions/libxt_nfacct.c
index 2ad59d52..d9c0309a 100644
--- a/extensions/libxt_nfacct.c
+++ b/extensions/libxt_nfacct.c
@@ -70,20 +70,36 @@ static void nfacct_save(const void *ip, const struct
xt_entry_match *match)
nfacct_print_name(info, "--");
}
-static struct xtables_match nfacct_match = {
- .family = NFPROTO_UNSPEC,
- .name = "nfacct",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_nfacct_match_info)),
- .userspacesize = offsetof(struct xt_nfacct_match_info, nfacct),
- .help = nfacct_help,
- .x6_parse = nfacct_parse,
- .print = nfacct_print,
- .save = nfacct_save,
- .x6_options = nfacct_opts,
+static struct xtables_match nfacct_matches[] = {
+ {
+ .family = NFPROTO_UNSPEC,
+ .revision = 0,
+ .name = "nfacct",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_nfacct_match_info)),
+ .userspacesize = offsetof(struct xt_nfacct_match_info, nfacct),
+ .help = nfacct_help,
+ .x6_parse = nfacct_parse,
+ .print = nfacct_print,
+ .save = nfacct_save,
+ .x6_options = nfacct_opts,
+ },
+ {
+ .family = NFPROTO_UNSPEC,
+ .revision = 1,
+ .name = "nfacct",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct
xt_nfacct_match_info_v1)),
+ .userspacesize = offsetof(struct xt_nfacct_match_info_v1,
nfacct),
+ .help = nfacct_help,
+ .x6_parse = nfacct_parse,
+ .print = nfacct_print,
+ .save = nfacct_save,
+ .x6_options = nfacct_opts,
+ },
};
void _init(void)
{
- xtables_register_match(&nfacct_match);
+ xtables_register_matches(nfacct_matches, ARRAY_SIZE(nfacct_matches));
}
diff --git a/include/linux/netfilter/xt_nfacct.h
b/include/linux/netfilter/xt_nfacct.h
index 59ab00dd..04ec2b04 100644
--- a/include/linux/netfilter/xt_nfacct.h
+++ b/include/linux/netfilter/xt_nfacct.h
@@ -14,4 +14,9 @@ struct xt_nfacct_match_info {
struct nf_acct *nfacct;
};
+struct xt_nfacct_match_info_v1 {
+ char name[NFACCT_NAME_MAX];
+ struct nf_acct *nfacct __attribute__((aligned(8)));
+};
+
#endif /* _XT_NFACCT_MATCH_H */
--
2.20.1