]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/net-sched-act_sample-fix-divide-by-zero-in-the-traff.patch
Linux 4.14.112
[thirdparty/kernel/stable-queue.git] / queue-4.19 / net-sched-act_sample-fix-divide-by-zero-in-the-traff.patch
1 From 5958b0053975a2b05945580195c41fb61b0cb258 Mon Sep 17 00:00:00 2001
2 From: Davide Caratti <dcaratti@redhat.com>
3 Date: Thu, 4 Apr 2019 12:31:35 +0200
4 Subject: net/sched: act_sample: fix divide by zero in the traffic path
5
6 [ Upstream commit fae2708174ae95d98d19f194e03d6e8f688ae195 ]
7
8 the control path of 'sample' action does not validate the value of 'rate'
9 provided by the user, but then it uses it as divisor in the traffic path.
10 Validate it in tcf_sample_init(), and return -EINVAL with a proper extack
11 message in case that value is zero, to fix a splat with the script below:
12
13 # tc f a dev test0 egress matchall action sample rate 0 group 1 index 2
14 # tc -s a s action sample
15 total acts 1
16
17 action order 0: sample rate 1/0 group 1 pipe
18 index 2 ref 1 bind 1 installed 19 sec used 19 sec
19 Action statistics:
20 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
21 backlog 0b 0p requeues 0
22 # ping 192.0.2.1 -I test0 -c1 -q
23
24 divide error: 0000 [#1] SMP PTI
25 CPU: 1 PID: 6192 Comm: ping Not tainted 5.1.0-rc2.diag2+ #591
26 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
27 RIP: 0010:tcf_sample_act+0x9e/0x1e0 [act_sample]
28 Code: 6a f1 85 c0 74 0d 80 3d 83 1a 00 00 00 0f 84 9c 00 00 00 4d 85 e4 0f 84 85 00 00 00 e8 9b d7 9c f1 44 8b 8b e0 00 00 00 31 d2 <41> f7 f1 85 d2 75 70 f6 85 83 00 00 00 10 48 8b 45 10 8b 88 08 01
29 RSP: 0018:ffffae320190ba30 EFLAGS: 00010246
30 RAX: 00000000b0677d21 RBX: ffff8af1ed9ec000 RCX: 0000000059a9fe49
31 RDX: 0000000000000000 RSI: 000000000c7e33b7 RDI: ffff8af23daa0af0
32 RBP: ffff8af1ee11b200 R08: 0000000074fcaf7e R09: 0000000000000000
33 R10: 0000000000000050 R11: ffffffffb3088680 R12: ffff8af232307f80
34 R13: 0000000000000003 R14: ffff8af1ed9ec000 R15: 0000000000000000
35 FS: 00007fe9c6d2f740(0000) GS:ffff8af23da80000(0000) knlGS:0000000000000000
36 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
37 CR2: 00007fff6772f000 CR3: 00000000746a2004 CR4: 00000000001606e0
38 Call Trace:
39 tcf_action_exec+0x7c/0x1c0
40 tcf_classify+0x57/0x160
41 __dev_queue_xmit+0x3dc/0xd10
42 ip_finish_output2+0x257/0x6d0
43 ip_output+0x75/0x280
44 ip_send_skb+0x15/0x40
45 raw_sendmsg+0xae3/0x1410
46 sock_sendmsg+0x36/0x40
47 __sys_sendto+0x10e/0x140
48 __x64_sys_sendto+0x24/0x30
49 do_syscall_64+0x60/0x210
50 entry_SYSCALL_64_after_hwframe+0x49/0xbe
51 [...]
52 Kernel panic - not syncing: Fatal exception in interrupt
53
54 Add a TDC selftest to document that 'rate' is now being validated.
55
56 Reported-by: Matteo Croce <mcroce@redhat.com>
57 Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action")
58 Signed-off-by: Davide Caratti <dcaratti@redhat.com>
59 Acked-by: Yotam Gigi <yotam.gi@gmail.com>
60 Signed-off-by: David S. Miller <davem@davemloft.net>
61 Signed-off-by: Sasha Levin <sashal@kernel.org>
62 ---
63 net/sched/act_sample.c | 10 ++++++--
64 .../tc-testing/tc-tests/actions/sample.json | 24 +++++++++++++++++++
65 2 files changed, 32 insertions(+), 2 deletions(-)
66
67 diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
68 index 6b67aa13d2dd..c7f5d630d97c 100644
69 --- a/net/sched/act_sample.c
70 +++ b/net/sched/act_sample.c
71 @@ -43,8 +43,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
72 struct tc_action_net *tn = net_generic(net, sample_net_id);
73 struct nlattr *tb[TCA_SAMPLE_MAX + 1];
74 struct psample_group *psample_group;
75 + u32 psample_group_num, rate;
76 struct tc_sample *parm;
77 - u32 psample_group_num;
78 struct tcf_sample *s;
79 bool exists = false;
80 int ret, err;
81 @@ -80,6 +80,12 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
82 return -EEXIST;
83 }
84
85 + rate = nla_get_u32(tb[TCA_SAMPLE_RATE]);
86 + if (!rate) {
87 + NL_SET_ERR_MSG(extack, "invalid sample rate");
88 + tcf_idr_release(*a, bind);
89 + return -EINVAL;
90 + }
91 psample_group_num = nla_get_u32(tb[TCA_SAMPLE_PSAMPLE_GROUP]);
92 psample_group = psample_group_get(net, psample_group_num);
93 if (!psample_group) {
94 @@ -91,7 +97,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
95
96 spin_lock_bh(&s->tcf_lock);
97 s->tcf_action = parm->action;
98 - s->rate = nla_get_u32(tb[TCA_SAMPLE_RATE]);
99 + s->rate = rate;
100 s->psample_group_num = psample_group_num;
101 RCU_INIT_POINTER(s->psample_group, psample_group);
102
103 diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json b/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json
104 index 3aca33c00039..618def9bdf0e 100644
105 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json
106 +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json
107 @@ -143,6 +143,30 @@
108 "$TC actions flush action sample"
109 ]
110 },
111 + {
112 + "id": "7571",
113 + "name": "Add sample action with invalid rate",
114 + "category": [
115 + "actions",
116 + "sample"
117 + ],
118 + "setup": [
119 + [
120 + "$TC actions flush action sample",
121 + 0,
122 + 1,
123 + 255
124 + ]
125 + ],
126 + "cmdUnderTest": "$TC actions add action sample rate 0 group 1 index 2",
127 + "expExitCode": "255",
128 + "verifyCmd": "$TC actions get action sample index 2",
129 + "matchPattern": "action order [0-9]+: sample rate 1/0 group 1.*index 2 ref",
130 + "matchCount": "0",
131 + "teardown": [
132 + "$TC actions flush action sample"
133 + ]
134 + },
135 {
136 "id": "b6d4",
137 "name": "Add sample action with mandatory arguments and invalid control action",
138 --
139 2.19.1
140