Skip to content

Commit e1201bc

Browse files
tammeladavem330
authored andcommitted
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>
1 parent 0c83c52 commit e1201bc

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

net/sched/act_pedit.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,16 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
251251
memcpy(nparms->tcfp_keys, parm->keys, ksize);
252252

253253
for (i = 0; i < nparms->tcfp_nkeys; ++i) {
254+
u32 offmask = nparms->tcfp_keys[i].offmask;
254255
u32 cur = nparms->tcfp_keys[i].off;
255256

257+
/* The AT option can be added to static offsets in the datapath */
258+
if (!offmask && cur % 4) {
259+
NL_SET_ERR_MSG_MOD(extack, "Offsets must be on 32bit boundaries");
260+
ret = -EINVAL;
261+
goto put_chain;
262+
}
263+
256264
/* sanitize the shift value for any later use */
257265
nparms->tcfp_keys[i].shift = min_t(size_t,
258266
BITS_PER_TYPE(int) - 1,
@@ -261,7 +269,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
261269
/* The AT option can read a single byte, we can bound the actual
262270
* value with uchar max.
263271
*/
264-
cur += (0xff & nparms->tcfp_keys[i].offmask) >> nparms->tcfp_keys[i].shift;
272+
cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;
265273

266274
/* Each key touches 4 bytes starting from the computed offset */
267275
nparms->tcfp_off_max_hint =
@@ -411,12 +419,12 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
411419
sizeof(_d), &_d);
412420
if (!d)
413421
goto bad;
414-
offset += (*d & tkey->offmask) >> tkey->shift;
415-
}
416422

417-
if (offset % 4) {
418-
pr_info("tc action pedit offset must be on 32 bit boundaries\n");
419-
goto bad;
423+
offset += (*d & tkey->offmask) >> tkey->shift;
424+
if (offset % 4) {
425+
pr_info("tc action pedit offset must be on 32 bit boundaries\n");
426+
goto bad;
427+
}
420428
}
421429

422430
if (!offset_valid(skb, hoffset + offset)) {

0 commit comments

Comments
 (0)