Commit 89a26cd4 authored by Juliana Rodrigueiro's avatar Juliana Rodrigueiro Committed by Pablo Neira Ayuso
Browse files

netfilter: xt_nfacct: Fix alignment mismatch in xt_nfacct_match_info



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

Trying to append nfacct related rules results in an unhelpful message.
Although it is suggested to look for more information in dmesg, nothing
can be found there.

    # iptables -A <chain> -m nfacct --nfacct-name <acct-object>
    iptables: Invalid argument. Run `dmesg' for more information.

This patch fixes the memory misalignment by enforcing 8-byte alignment
within the struct's first revision. This solution is often used in many
other uapi netfilter headers.

Signed-off-by: default avatarJuliana Rodrigueiro <juliana.rodrigueiro@intra2net.com>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 14c41586
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -11,4 +11,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 */
+25 −11
Original line number Diff line number Diff line
@@ -54,8 +54,10 @@ nfacct_mt_destroy(const struct xt_mtdtor_param *par)
	nfnl_acct_put(info->nfacct);
}

static struct xt_match nfacct_mt_reg __read_mostly = {
static struct xt_match nfacct_mt_reg[] __read_mostly = {
	{
		.name       = "nfacct",
		.revision   = 0,
		.family     = NFPROTO_UNSPEC,
		.checkentry = nfacct_mt_checkentry,
		.match      = nfacct_mt,
@@ -63,16 +65,28 @@ static struct xt_match nfacct_mt_reg __read_mostly = {
		.matchsize  = sizeof(struct xt_nfacct_match_info),
		.usersize   = offsetof(struct xt_nfacct_match_info, nfacct),
		.me         = THIS_MODULE,
	},
	{
		.name       = "nfacct",
		.revision   = 1,
		.family     = NFPROTO_UNSPEC,
		.checkentry = nfacct_mt_checkentry,
		.match      = nfacct_mt,
		.destroy    = nfacct_mt_destroy,
		.matchsize  = sizeof(struct xt_nfacct_match_info_v1),
		.usersize   = offsetof(struct xt_nfacct_match_info_v1, nfacct),
		.me         = THIS_MODULE,
	},
};

static int __init nfacct_mt_init(void)
{
	return xt_register_match(&nfacct_mt_reg);
	return xt_register_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
}

static void __exit nfacct_mt_exit(void)
{
	xt_unregister_match(&nfacct_mt_reg);
	xt_unregister_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
}

module_init(nfacct_mt_init);