mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
net/sched: act_pedit: check static offsets a priori
Static key offsets should always be on 32 bit boundaries. Validate them on create/update time for static offsets and move the datapath validation for runtime offsets only. iproute2 already errors out if a given offset and data size cannot be packed to a 32 bit boundary. This change will make sure users which create/update pedit instances directly via netlink also error out, instead of finding out when packets are traversing. Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: Pedro Tammela <pctammela@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0c83c5210e
commit
e1201bc781
@ -251,8 +251,16 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
||||
memcpy(nparms->tcfp_keys, parm->keys, ksize);
|
||||
|
||||
for (i = 0; i < nparms->tcfp_nkeys; ++i) {
|
||||
u32 offmask = nparms->tcfp_keys[i].offmask;
|
||||
u32 cur = nparms->tcfp_keys[i].off;
|
||||
|
||||
/* The AT option can be added to static offsets in the datapath */
|
||||
if (!offmask && cur % 4) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Offsets must be on 32bit boundaries");
|
||||
ret = -EINVAL;
|
||||
goto put_chain;
|
||||
}
|
||||
|
||||
/* sanitize the shift value for any later use */
|
||||
nparms->tcfp_keys[i].shift = min_t(size_t,
|
||||
BITS_PER_TYPE(int) - 1,
|
||||
@ -261,7 +269,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
||||
/* The AT option can read a single byte, we can bound the actual
|
||||
* value with uchar max.
|
||||
*/
|
||||
cur += (0xff & nparms->tcfp_keys[i].offmask) >> nparms->tcfp_keys[i].shift;
|
||||
cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;
|
||||
|
||||
/* Each key touches 4 bytes starting from the computed offset */
|
||||
nparms->tcfp_off_max_hint =
|
||||
@ -411,12 +419,12 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
|
||||
sizeof(_d), &_d);
|
||||
if (!d)
|
||||
goto bad;
|
||||
offset += (*d & tkey->offmask) >> tkey->shift;
|
||||
}
|
||||
|
||||
if (offset % 4) {
|
||||
pr_info("tc action pedit offset must be on 32 bit boundaries\n");
|
||||
goto bad;
|
||||
offset += (*d & tkey->offmask) >> tkey->shift;
|
||||
if (offset % 4) {
|
||||
pr_info("tc action pedit offset must be on 32 bit boundaries\n");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
if (!offset_valid(skb, hoffset + offset)) {
|
||||
|
Loading…
Reference in New Issue
Block a user