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 <juliana.rodrigueiro@xxxxxxxxxxxxx> --- 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