1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (C) 2023 SUSE LLC
4*49cdfc7eSAndroid Build Coastguard Worker * Author: Marcos Paulo de Souza <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker * LTP port: Martin Doucha <[email protected]>
6*49cdfc7eSAndroid Build Coastguard Worker */
7*49cdfc7eSAndroid Build Coastguard Worker
8*49cdfc7eSAndroid Build Coastguard Worker /*\
9*49cdfc7eSAndroid Build Coastguard Worker * CVE-2023-1829
10*49cdfc7eSAndroid Build Coastguard Worker *
11*49cdfc7eSAndroid Build Coastguard Worker * Test for use-after-free after removing tcindex traffic filter with certain
12*49cdfc7eSAndroid Build Coastguard Worker * parameters.
13*49cdfc7eSAndroid Build Coastguard Worker *
14*49cdfc7eSAndroid Build Coastguard Worker * Tcindex filter removed in:
15*49cdfc7eSAndroid Build Coastguard Worker *
16*49cdfc7eSAndroid Build Coastguard Worker * commit 8c710f75256bb3cf05ac7b1672c82b92c43f3d28
17*49cdfc7eSAndroid Build Coastguard Worker * Author: Jamal Hadi Salim <[email protected]>
18*49cdfc7eSAndroid Build Coastguard Worker * Date: Tue Feb 14 08:49:14 2023 -0500
19*49cdfc7eSAndroid Build Coastguard Worker *
20*49cdfc7eSAndroid Build Coastguard Worker * net/sched: Retire tcindex classifier
21*49cdfc7eSAndroid Build Coastguard Worker */
22*49cdfc7eSAndroid Build Coastguard Worker
23*49cdfc7eSAndroid Build Coastguard Worker #include <linux/netlink.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include <linux/pkt_sched.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <linux/pkt_cls.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
27*49cdfc7eSAndroid Build Coastguard Worker #include "tst_netlink.h"
28*49cdfc7eSAndroid Build Coastguard Worker #include "tst_netdevice.h"
29*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/sched.h"
30*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/if_ether.h"
31*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/rtnetlink.h"
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker #define DEVNAME "ltp_dummy1"
34*49cdfc7eSAndroid Build Coastguard Worker
35*49cdfc7eSAndroid Build Coastguard Worker #ifndef TCA_TCINDEX_MAX
36*49cdfc7eSAndroid Build Coastguard Worker enum {
37*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_UNSPEC,
38*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_HASH,
39*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_MASK,
40*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_SHIFT,
41*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_FALL_THROUGH,
42*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_CLASSID,
43*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_POLICE,
44*49cdfc7eSAndroid Build Coastguard Worker TCA_TCINDEX_ACT,
45*49cdfc7eSAndroid Build Coastguard Worker __TCA_TCINDEX_MAX
46*49cdfc7eSAndroid Build Coastguard Worker };
47*49cdfc7eSAndroid Build Coastguard Worker
48*49cdfc7eSAndroid Build Coastguard Worker #define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
49*49cdfc7eSAndroid Build Coastguard Worker #endif
50*49cdfc7eSAndroid Build Coastguard Worker
51*49cdfc7eSAndroid Build Coastguard Worker
52*49cdfc7eSAndroid Build Coastguard Worker static const uint32_t qd_handle = TC_H_MAKE(1 << 16, 0);
53*49cdfc7eSAndroid Build Coastguard Worker static const uint32_t clsid = TC_H_MAKE(1 << 16, 1);
54*49cdfc7eSAndroid Build Coastguard Worker static const uint32_t shift = 10;
55*49cdfc7eSAndroid Build Coastguard Worker static const uint16_t mask = 0xffff;
56*49cdfc7eSAndroid Build Coastguard Worker
57*49cdfc7eSAndroid Build Coastguard Worker /* rtnetlink payloads */
58*49cdfc7eSAndroid Build Coastguard Worker static const struct tc_htb_glob qd_opt = {
59*49cdfc7eSAndroid Build Coastguard Worker .rate2quantum = 10,
60*49cdfc7eSAndroid Build Coastguard Worker .version = 3,
61*49cdfc7eSAndroid Build Coastguard Worker .defcls = 30
62*49cdfc7eSAndroid Build Coastguard Worker };
63*49cdfc7eSAndroid Build Coastguard Worker static struct tc_htb_opt cls_opt = {};
64*49cdfc7eSAndroid Build Coastguard Worker
65*49cdfc7eSAndroid Build Coastguard Worker /* htb qdisc and class options */
66*49cdfc7eSAndroid Build Coastguard Worker static const struct tst_netlink_attr_list qd_config[] = {
67*49cdfc7eSAndroid Build Coastguard Worker {TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
68*49cdfc7eSAndroid Build Coastguard Worker {TCA_HTB_INIT, &qd_opt, sizeof(qd_opt), NULL},
69*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
70*49cdfc7eSAndroid Build Coastguard Worker }},
71*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
72*49cdfc7eSAndroid Build Coastguard Worker };
73*49cdfc7eSAndroid Build Coastguard Worker static const struct tst_netlink_attr_list cls_config[] = {
74*49cdfc7eSAndroid Build Coastguard Worker {TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
75*49cdfc7eSAndroid Build Coastguard Worker {TCA_HTB_PARMS, &cls_opt, sizeof(cls_opt), NULL},
76*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
77*49cdfc7eSAndroid Build Coastguard Worker }},
78*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
79*49cdfc7eSAndroid Build Coastguard Worker };
80*49cdfc7eSAndroid Build Coastguard Worker
81*49cdfc7eSAndroid Build Coastguard Worker /* tcindex filter options */
82*49cdfc7eSAndroid Build Coastguard Worker static const struct tst_netlink_attr_list f_config[] = {
83*49cdfc7eSAndroid Build Coastguard Worker {TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
84*49cdfc7eSAndroid Build Coastguard Worker {TCA_TCINDEX_MASK, &mask, sizeof(mask), NULL},
85*49cdfc7eSAndroid Build Coastguard Worker {TCA_TCINDEX_SHIFT, &shift, sizeof(shift), NULL},
86*49cdfc7eSAndroid Build Coastguard Worker {TCA_TCINDEX_CLASSID, &clsid, sizeof(clsid), NULL},
87*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
88*49cdfc7eSAndroid Build Coastguard Worker }},
89*49cdfc7eSAndroid Build Coastguard Worker {0, NULL, -1, NULL}
90*49cdfc7eSAndroid Build Coastguard Worker };
91*49cdfc7eSAndroid Build Coastguard Worker
setup(void)92*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
93*49cdfc7eSAndroid Build Coastguard Worker {
94*49cdfc7eSAndroid Build Coastguard Worker tst_setup_netns();
95*49cdfc7eSAndroid Build Coastguard Worker NETDEV_ADD_DEVICE(DEVNAME, "dummy");
96*49cdfc7eSAndroid Build Coastguard Worker
97*49cdfc7eSAndroid Build Coastguard Worker cls_opt.rate.rate = cls_opt.ceil.rate = 256000;
98*49cdfc7eSAndroid Build Coastguard Worker cls_opt.buffer = 1000000 * 1600 / cls_opt.rate.rate;
99*49cdfc7eSAndroid Build Coastguard Worker cls_opt.cbuffer = 1000000 * 1600 / cls_opt.ceil.rate;
100*49cdfc7eSAndroid Build Coastguard Worker }
101*49cdfc7eSAndroid Build Coastguard Worker
run(void)102*49cdfc7eSAndroid Build Coastguard Worker static void run(void)
103*49cdfc7eSAndroid Build Coastguard Worker {
104*49cdfc7eSAndroid Build Coastguard Worker int ret;
105*49cdfc7eSAndroid Build Coastguard Worker
106*49cdfc7eSAndroid Build Coastguard Worker NETDEV_ADD_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb",
107*49cdfc7eSAndroid Build Coastguard Worker qd_config);
108*49cdfc7eSAndroid Build Coastguard Worker NETDEV_ADD_TRAFFIC_CLASS(DEVNAME, qd_handle, clsid, "htb", cls_config);
109*49cdfc7eSAndroid Build Coastguard Worker ret = NETDEV_ADD_TRAFFIC_FILTER_RET(DEVNAME, qd_handle, 10, ETH_P_IP,
110*49cdfc7eSAndroid Build Coastguard Worker 1, "tcindex", f_config);
111*49cdfc7eSAndroid Build Coastguard Worker TST_ERR = tst_netlink_errno;
112*49cdfc7eSAndroid Build Coastguard Worker
113*49cdfc7eSAndroid Build Coastguard Worker if (!ret && TST_ERR == ENOENT) {
114*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS | TTERRNO,
115*49cdfc7eSAndroid Build Coastguard Worker "tcindex module is blacklisted or unavailable");
116*49cdfc7eSAndroid Build Coastguard Worker return;
117*49cdfc7eSAndroid Build Coastguard Worker }
118*49cdfc7eSAndroid Build Coastguard Worker
119*49cdfc7eSAndroid Build Coastguard Worker if (!ret)
120*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "Cannot add tcindex filter");
121*49cdfc7eSAndroid Build Coastguard Worker
122*49cdfc7eSAndroid Build Coastguard Worker NETDEV_REMOVE_TRAFFIC_FILTER(DEVNAME, qd_handle, 10, ETH_P_IP,
123*49cdfc7eSAndroid Build Coastguard Worker 1, "tcindex");
124*49cdfc7eSAndroid Build Coastguard Worker ret = NETDEV_ADD_TRAFFIC_FILTER_RET(DEVNAME, qd_handle, 10, ETH_P_IP,
125*49cdfc7eSAndroid Build Coastguard Worker 1, "tcindex", f_config);
126*49cdfc7eSAndroid Build Coastguard Worker TST_ERR = tst_netlink_errno;
127*49cdfc7eSAndroid Build Coastguard Worker NETDEV_REMOVE_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb");
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard Worker if (ret)
130*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Removing tcindex filter works correctly");
131*49cdfc7eSAndroid Build Coastguard Worker else if (TST_ERR == EEXIST)
132*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Kernel traffic filter list is corrupted");
133*49cdfc7eSAndroid Build Coastguard Worker else
134*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "Unexpected rtnetlink error");
135*49cdfc7eSAndroid Build Coastguard Worker }
136*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)137*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
138*49cdfc7eSAndroid Build Coastguard Worker {
139*49cdfc7eSAndroid Build Coastguard Worker NETDEV_REMOVE_DEVICE(DEVNAME);
140*49cdfc7eSAndroid Build Coastguard Worker }
141*49cdfc7eSAndroid Build Coastguard Worker
142*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
143*49cdfc7eSAndroid Build Coastguard Worker .test_all = run,
144*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
145*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup,
146*49cdfc7eSAndroid Build Coastguard Worker .taint_check = TST_TAINT_W | TST_TAINT_D,
147*49cdfc7eSAndroid Build Coastguard Worker .needs_kconfigs = (const char *[]) {
148*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_VETH",
149*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_USER_NS=y",
150*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_NET_NS=y",
151*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_NET_SCH_HTB",
152*49cdfc7eSAndroid Build Coastguard Worker "CONFIG_NET_CLS_TCINDEX",
153*49cdfc7eSAndroid Build Coastguard Worker NULL
154*49cdfc7eSAndroid Build Coastguard Worker },
155*49cdfc7eSAndroid Build Coastguard Worker .save_restore = (const struct tst_path_val[]) {
156*49cdfc7eSAndroid Build Coastguard Worker {"/proc/sys/user/max_user_namespaces", "1024", TST_SR_SKIP},
157*49cdfc7eSAndroid Build Coastguard Worker {}
158*49cdfc7eSAndroid Build Coastguard Worker },
159*49cdfc7eSAndroid Build Coastguard Worker .needs_drivers = (const char *const []) {
160*49cdfc7eSAndroid Build Coastguard Worker "dummy",
161*49cdfc7eSAndroid Build Coastguard Worker NULL
162*49cdfc7eSAndroid Build Coastguard Worker },
163*49cdfc7eSAndroid Build Coastguard Worker .tags = (const struct tst_tag[]) {
164*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "8c710f75256b"},
165*49cdfc7eSAndroid Build Coastguard Worker {"CVE", "2023-1829"},
166*49cdfc7eSAndroid Build Coastguard Worker {}
167*49cdfc7eSAndroid Build Coastguard Worker }
168*49cdfc7eSAndroid Build Coastguard Worker };
169