Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81d15944 authored by Davide Caratti's avatar Davide Caratti Committed by Greg Kroah-Hartman
Browse files

net/sched: act_simple: fix parsing of TCA_DEF_DATA



[ Upstream commit 8d499533e0bc02d44283dbdab03142b599b8ba16 ]

use nla_strlcpy() to avoid copying data beyond the length of TCA_DEF_DATA
netlink attribute, in case it is less than SIMP_MAX_DATA and it does not
end with '\0' character.

v2: fix errors in the commit message, thanks Hangbin Liu

Fixes: fa1b1cff ("net_cls_act: Make act_simple use of netlink policy.")
Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 73c0eab8
Loading
Loading
Loading
Loading
+6 −9
Original line number Original line Diff line number Diff line
@@ -53,22 +53,22 @@ static void tcf_simp_release(struct tc_action *a, int bind)
	kfree(d->tcfd_defdata);
	kfree(d->tcfd_defdata);
}
}


static int alloc_defdata(struct tcf_defact *d, char *defdata)
static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata)
{
{
	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
	if (unlikely(!d->tcfd_defdata))
	if (unlikely(!d->tcfd_defdata))
		return -ENOMEM;
		return -ENOMEM;
	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
	return 0;
	return 0;
}
}


static void reset_policy(struct tcf_defact *d, char *defdata,
static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata,
			 struct tc_defact *p)
			 struct tc_defact *p)
{
{
	spin_lock_bh(&d->tcf_lock);
	spin_lock_bh(&d->tcf_lock);
	d->tcf_action = p->action;
	d->tcf_action = p->action;
	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
	spin_unlock_bh(&d->tcf_lock);
	spin_unlock_bh(&d->tcf_lock);
}
}


@@ -87,7 +87,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
	struct tcf_defact *d;
	struct tcf_defact *d;
	bool exists = false;
	bool exists = false;
	int ret = 0, err;
	int ret = 0, err;
	char *defdata;


	if (nla == NULL)
	if (nla == NULL)
		return -EINVAL;
		return -EINVAL;
@@ -110,8 +109,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
		return -EINVAL;
		return -EINVAL;
	}
	}


	defdata = nla_data(tb[TCA_DEF_DATA]);

	if (!exists) {
	if (!exists) {
		ret = tcf_idr_create(tn, parm->index, est, a,
		ret = tcf_idr_create(tn, parm->index, est, a,
				     &act_simp_ops, bind, false);
				     &act_simp_ops, bind, false);
@@ -119,7 +116,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
			return ret;
			return ret;


		d = to_defact(*a);
		d = to_defact(*a);
		ret = alloc_defdata(d, defdata);
		ret = alloc_defdata(d, tb[TCA_DEF_DATA]);
		if (ret < 0) {
		if (ret < 0) {
			tcf_idr_release(*a, bind);
			tcf_idr_release(*a, bind);
			return ret;
			return ret;
@@ -133,7 +130,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
		if (!ovr)
		if (!ovr)
			return -EEXIST;
			return -EEXIST;


		reset_policy(d, defdata, parm);
		reset_policy(d, tb[TCA_DEF_DATA], parm);
	}
	}


	if (ret == ACT_P_CREATED)
	if (ret == ACT_P_CREATED)