Skip to content

Commit 76bd285

Browse files
tammelabmastbergen
authored andcommitted
net/sched: act_pedit: fix action bind logic
jira VULN-188478 cve-pre CVE-2026-46331 commit-author Rajat Gupta <rajat.gupta@oss.qualcomm.com> commit e9e4229 The TC architecture allows filters and actions to be created independently. In filters the user can reference action objects using: tc action add action pedit ... index 1 tc filter add ... action pedit index 1 In the current code for act_pedit this is broken as it checks netlink attributes for create/update before actually checking if we are binding to an existing action. tdc results: 1..69 ok 1 319a - Add pedit action that mangles IP TTL ok 2 7e67 - Replace pedit action with invalid goto chain ok 3 377e - Add pedit action with RAW_OP offset u32 ok 4 a0ca - Add pedit action with RAW_OP offset u32 (INVALID) ok 5 dd8a - Add pedit action with RAW_OP offset u16 u16 ok 6 53db - Add pedit action with RAW_OP offset u16 (INVALID) ok 7 5c7e - Add pedit action with RAW_OP offset u8 add value ok 8 2893 - Add pedit action with RAW_OP offset u8 quad ok 9 3a07 - Add pedit action with RAW_OP offset u8-u16-u8 ok 10 ab0f - Add pedit action with RAW_OP offset u16-u8-u8 ok 11 9d12 - Add pedit action with RAW_OP offset u32 set u16 clear u8 invert ok 12 ebfa - Add pedit action with RAW_OP offset overflow u32 (INVALID) ok 13 f512 - Add pedit action with RAW_OP offset u16 at offmask shift set ok 14 c2cb - Add pedit action with RAW_OP offset u32 retain value ok 15 1762 - Add pedit action with RAW_OP offset u8 clear value ok 16 bcee - Add pedit action with RAW_OP offset u8 retain value ok 17 e89f - Add pedit action with RAW_OP offset u16 retain value ok 18 c282 - Add pedit action with RAW_OP offset u32 clear value ok 19 c422 - Add pedit action with RAW_OP offset u16 invert value ok 20 d3d3 - Add pedit action with RAW_OP offset u32 invert value ok 21 57e5 - Add pedit action with RAW_OP offset u8 preserve value ok 22 99e0 - Add pedit action with RAW_OP offset u16 preserve value ok 23 1892 - Add pedit action with RAW_OP offset u32 preserve value ok 24 4b60 - Add pedit action with RAW_OP negative offset u16/u32 set value ok 25 a5a7 - Add pedit action with LAYERED_OP eth set src ok 26 86d4 - Add pedit action with LAYERED_OP eth set src & dst ok 27 f8a9 - Add pedit action with LAYERED_OP eth set dst ok 28 c715 - Add pedit action with LAYERED_OP eth set src (INVALID) ok 29 8131 - Add pedit action with LAYERED_OP eth set dst (INVALID) ok 30 ba22 - Add pedit action with LAYERED_OP eth type set/clear sequence ok 31 dec4 - Add pedit action with LAYERED_OP eth set type (INVALID) ok 32 ab06 - Add pedit action with LAYERED_OP eth add type ok 33 918d - Add pedit action with LAYERED_OP eth invert src ok 34 a8d4 - Add pedit action with LAYERED_OP eth invert dst ok 35 ee13 - Add pedit action with LAYERED_OP eth invert type ok 36 7588 - Add pedit action with LAYERED_OP ip set src ok 37 0fa7 - Add pedit action with LAYERED_OP ip set dst ok 38 5810 - Add pedit action with LAYERED_OP ip set src & dst ok 39 1092 - Add pedit action with LAYERED_OP ip set ihl & dsfield ok 40 02d8 - Add pedit action with LAYERED_OP ip set ttl & protocol ok 41 3e2d - Add pedit action with LAYERED_OP ip set ttl (INVALID) ok 42 31ae - Add pedit action with LAYERED_OP ip ttl clear/set ok 43 486f - Add pedit action with LAYERED_OP ip set duplicate fields ok 44 e790 - Add pedit action with LAYERED_OP ip set ce, df, mf, firstfrag, nofrag fields ok 45 cc8a - Add pedit action with LAYERED_OP ip set tos ok 46 7a17 - Add pedit action with LAYERED_OP ip set precedence ok 47 c3b6 - Add pedit action with LAYERED_OP ip add tos ok 48 43d3 - Add pedit action with LAYERED_OP ip add precedence ok 49 438e - Add pedit action with LAYERED_OP ip clear tos ok 50 6b1b - Add pedit action with LAYERED_OP ip clear precedence ok 51 824a - Add pedit action with LAYERED_OP ip invert tos ok 52 106f - Add pedit action with LAYERED_OP ip invert precedence ok 53 6829 - Add pedit action with LAYERED_OP beyond ip set dport & sport ok 54 afd8 - Add pedit action with LAYERED_OP beyond ip set icmp_type & icmp_code ok 55 3143 - Add pedit action with LAYERED_OP beyond ip set dport (INVALID) ok 56 815c - Add pedit action with LAYERED_OP ip6 set src ok 57 4dae - Add pedit action with LAYERED_OP ip6 set dst ok 58 fc1f - Add pedit action with LAYERED_OP ip6 set src & dst ok 59 6d34 - Add pedit action with LAYERED_OP ip6 dst retain value (INVALID) ok 60 94bb - Add pedit action with LAYERED_OP ip6 traffic_class ok 61 6f5e - Add pedit action with LAYERED_OP ip6 flow_lbl ok 62 6795 - Add pedit action with LAYERED_OP ip6 set payload_len, nexthdr, hoplimit ok 63 1442 - Add pedit action with LAYERED_OP tcp set dport & sport ok 64 b7ac - Add pedit action with LAYERED_OP tcp sport set (INVALID) ok 65 cfcc - Add pedit action with LAYERED_OP tcp flags set ok 66 3bc4 - Add pedit action with LAYERED_OP tcp set dport, sport & flags fields ok 67 f1c8 - Add pedit action with LAYERED_OP udp set dport & sport ok 68 d784 - Add pedit action with mixed RAW/LAYERED_OP #1 ok 69 70ca - Add pedit action with mixed RAW/LAYERED_OP #2 Fixes: 71d0ed7 ("net/act_pedit: Support using offset relative to the conventional network headers") Fixes: f67169f ("net/sched: act_pedit: fix WARN() in the traffic path") Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Pedro Tammela <pctammela@mojatatu.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit e9e4229) Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 8ac01b4 commit 76bd285

1 file changed

Lines changed: 31 additions & 27 deletions

File tree

net/sched/act_pedit.c

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
183183
}
184184

185185
parm = nla_data(pattr);
186-
if (!parm->nkeys) {
187-
NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
188-
return -EINVAL;
189-
}
190-
ksize = parm->nkeys * sizeof(struct tc_pedit_key);
191-
if (nla_len(pattr) < sizeof(*parm) + ksize) {
192-
NL_SET_ERR_MSG_ATTR(extack, pattr, "Length of TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute is invalid");
193-
return -EINVAL;
194-
}
195-
196-
nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
197-
if (!nparms)
198-
return -ENOMEM;
199-
200-
nparms->tcfp_keys_ex =
201-
tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
202-
if (IS_ERR(nparms->tcfp_keys_ex)) {
203-
ret = PTR_ERR(nparms->tcfp_keys_ex);
204-
goto out_free;
205-
}
206186

207187
index = parm->index;
208188
err = tcf_idr_check_alloc(tn, &index, a, bind);
@@ -211,25 +191,49 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
211191
&act_pedit_ops, bind, flags);
212192
if (ret) {
213193
tcf_idr_cleanup(tn, index);
214-
goto out_free_ex;
194+
return ret;
215195
}
216196
ret = ACT_P_CREATED;
217197
} else if (err > 0) {
218198
if (bind)
219-
goto out_free;
199+
return 0;
220200
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
221201
ret = -EEXIST;
222202
goto out_release;
223203
}
224204
} else {
225-
ret = err;
226-
goto out_free_ex;
205+
return err;
206+
}
207+
208+
if (!parm->nkeys) {
209+
NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
210+
ret = -EINVAL;
211+
goto out_release;
212+
}
213+
ksize = parm->nkeys * sizeof(struct tc_pedit_key);
214+
if (nla_len(pattr) < sizeof(*parm) + ksize) {
215+
NL_SET_ERR_MSG_ATTR(extack, pattr, "Length of TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute is invalid");
216+
ret = -EINVAL;
217+
goto out_release;
218+
}
219+
220+
nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
221+
if (!nparms) {
222+
ret = -ENOMEM;
223+
goto out_release;
224+
}
225+
226+
nparms->tcfp_keys_ex =
227+
tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
228+
if (IS_ERR(nparms->tcfp_keys_ex)) {
229+
ret = PTR_ERR(nparms->tcfp_keys_ex);
230+
goto out_free;
227231
}
228232

229233
err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
230234
if (err < 0) {
231235
ret = err;
232-
goto out_release;
236+
goto out_free_ex;
233237
}
234238

235239
nparms->tcfp_off_max_hint = 0;
@@ -290,12 +294,12 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
290294
put_chain:
291295
if (goto_ch)
292296
tcf_chain_put_by_act(goto_ch);
293-
out_release:
294-
tcf_idr_release(*a, bind);
295297
out_free_ex:
296298
kfree(nparms->tcfp_keys_ex);
297299
out_free:
298300
kfree(nparms);
301+
out_release:
302+
tcf_idr_release(*a, bind);
299303
return ret;
300304
}
301305

0 commit comments

Comments
 (0)