Commit c7d13358 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: xt_SECMARK: add new revision to fix structure layout



This extension breaks when trying to delete rules, add a new revision to
fix this.

Fixes: 5e6874cd ("[SECMARK]: Add xtables SECMARK target")
Signed-off-by: default avatarPhil Sutter <phil@nwl.cc>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent bd1af6b5
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -20,4 +20,10 @@ struct xt_secmark_target_info {
	char secctx[SECMARK_SECCTX_MAX];
};

struct xt_secmark_target_info_v1 {
	__u8 mode;
	char secctx[SECMARK_SECCTX_MAX];
	__u32 secid;
};

#endif /*_XT_SECMARK_H_target */
+69 −19
Original line number Diff line number Diff line
@@ -24,10 +24,9 @@ MODULE_ALIAS("ip6t_SECMARK");
static u8 mode;

static unsigned int
secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
secmark_tg(struct sk_buff *skb, const struct xt_secmark_target_info_v1 *info)
{
	u32 secmark = 0;
	const struct xt_secmark_target_info *info = par->targinfo;

	switch (mode) {
	case SECMARK_MODE_SEL:
@@ -41,7 +40,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
	return XT_CONTINUE;
}

static int checkentry_lsm(struct xt_secmark_target_info *info)
static int checkentry_lsm(struct xt_secmark_target_info_v1 *info)
{
	int err;

@@ -73,15 +72,15 @@ static int checkentry_lsm(struct xt_secmark_target_info *info)
	return 0;
}

static int secmark_tg_check(const struct xt_tgchk_param *par)
static int
secmark_tg_check(const char *table, struct xt_secmark_target_info_v1 *info)
{
	struct xt_secmark_target_info *info = par->targinfo;
	int err;

	if (strcmp(par->table, "mangle") != 0 &&
	    strcmp(par->table, "security") != 0) {
	if (strcmp(table, "mangle") != 0 &&
	    strcmp(table, "security") != 0) {
		pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
				    par->table);
				    table);
		return -EINVAL;
	}

@@ -116,25 +115,76 @@ static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
	}
}

static struct xt_target secmark_tg_reg __read_mostly = {
static int secmark_tg_check_v0(const struct xt_tgchk_param *par)
{
	struct xt_secmark_target_info *info = par->targinfo;
	struct xt_secmark_target_info_v1 newinfo = {
		.mode	= info->mode,
	};
	int ret;

	memcpy(newinfo.secctx, info->secctx, SECMARK_SECCTX_MAX);

	ret = secmark_tg_check(par->table, &newinfo);
	info->secid = newinfo.secid;

	return ret;
}

static unsigned int
secmark_tg_v0(struct sk_buff *skb, const struct xt_action_param *par)
{
	const struct xt_secmark_target_info *info = par->targinfo;
	struct xt_secmark_target_info_v1 newinfo = {
		.secid	= info->secid,
	};

	return secmark_tg(skb, &newinfo);
}

static int secmark_tg_check_v1(const struct xt_tgchk_param *par)
{
	return secmark_tg_check(par->table, par->targinfo);
}

static unsigned int
secmark_tg_v1(struct sk_buff *skb, const struct xt_action_param *par)
{
	return secmark_tg(skb, par->targinfo);
}

static struct xt_target secmark_tg_reg[] __read_mostly = {
	{
		.name		= "SECMARK",
		.revision	= 0,
		.family		= NFPROTO_UNSPEC,
	.checkentry = secmark_tg_check,
		.checkentry	= secmark_tg_check_v0,
		.destroy	= secmark_tg_destroy,
	.target     = secmark_tg,
		.target		= secmark_tg_v0,
		.targetsize	= sizeof(struct xt_secmark_target_info),
		.me		= THIS_MODULE,
	},
	{
		.name		= "SECMARK",
		.revision	= 1,
		.family		= NFPROTO_UNSPEC,
		.checkentry	= secmark_tg_check_v1,
		.destroy	= secmark_tg_destroy,
		.target		= secmark_tg_v1,
		.targetsize	= sizeof(struct xt_secmark_target_info_v1),
		.usersize	= offsetof(struct xt_secmark_target_info_v1, secid),
		.me		= THIS_MODULE,
	},
};

static int __init secmark_tg_init(void)
{
	return xt_register_target(&secmark_tg_reg);
	return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
}

static void __exit secmark_tg_exit(void)
{
	xt_unregister_target(&secmark_tg_reg);
	xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
}

module_init(secmark_tg_init);