xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/bind/bind06.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2020 SUSE LLC <[email protected]>
4  *
5  * CVE-2018-18559
6  *
7  * Test for race condition vulnerability in bind() on AF_PACKET socket.
8  * Fixed in:
9  *
10  *  commit 15fe076edea787807a7cdc168df832544b58eba6
11  *  Author: Eric Dumazet <[email protected]>
12  *  Date:   Tue Nov 28 08:03:30 2017 -0800
13  *
14  *  net/packet: fix a race in packet_bind() and packet_notifier()
15  */
16 
17 #include <sys/socket.h>
18 #include <sys/ioctl.h>
19 #include <linux/if_packet.h>
20 #include <net/ethernet.h>
21 #include <net/if.h>
22 #include "tst_test.h"
23 #include "tst_fuzzy_sync.h"
24 
25 static volatile int fd = -1;
26 static struct sockaddr_ll addr1, addr2;
27 static struct tst_fzsync_pair fzsync_pair;
28 
setup(void)29 static void setup(void)
30 {
31 	struct ifreq ifr;
32 
33 	tst_setup_netns();
34 
35 	fd = SAFE_SOCKET(AF_PACKET, SOCK_DGRAM, PF_PACKET);
36 	strcpy(ifr.ifr_name, "lo");
37 	SAFE_IOCTL(fd, SIOCGIFINDEX, &ifr);
38 	SAFE_CLOSE(fd);
39 
40 	addr1.sll_family = AF_PACKET;
41 	addr1.sll_ifindex = ifr.ifr_ifindex;
42 	addr2.sll_family = AF_PACKET;
43 
44 	fzsync_pair.exec_loops = 10000;
45 	tst_fzsync_pair_init(&fzsync_pair);
46 }
47 
cleanup(void)48 static void cleanup(void)
49 {
50 	tst_fzsync_pair_cleanup(&fzsync_pair);
51 }
52 
do_bind(void)53 static void do_bind(void)
54 {
55 	SAFE_BIND(fd, (struct sockaddr *)&addr1, sizeof(addr1));
56 	SAFE_BIND(fd, (struct sockaddr *)&addr2, sizeof(addr2));
57 }
58 
thread_run(void * arg)59 static void *thread_run(void *arg)
60 {
61 	while (tst_fzsync_run_b(&fzsync_pair)) {
62 		tst_fzsync_start_race_b(&fzsync_pair);
63 		do_bind();
64 		tst_fzsync_end_race_b(&fzsync_pair);
65 	}
66 
67 	return arg;
68 }
69 
run(void)70 static void run(void)
71 {
72 	struct ifreq ifr;
73 
74 	tst_fzsync_pair_reset(&fzsync_pair, thread_run);
75 	strcpy(ifr.ifr_name, "lo");
76 
77 	while (tst_fzsync_run_a(&fzsync_pair)) {
78 		fd = SAFE_SOCKET(AF_PACKET, SOCK_DGRAM, PF_PACKET);
79 		ifr.ifr_flags = 0;
80 		ioctl(fd, SIOCSIFFLAGS, &ifr);
81 		ifr.ifr_flags = IFF_UP;
82 		tst_fzsync_start_race_a(&fzsync_pair);
83 		ioctl(fd, SIOCSIFFLAGS, &ifr);
84 		tst_fzsync_end_race_a(&fzsync_pair);
85 		SAFE_CLOSE(fd);
86 	}
87 
88 	tst_res(TPASS, "Nothing bad happened (yet)");
89 }
90 
91 static struct tst_test test = {
92 	.test_all = run,
93 	.setup = setup,
94 	.cleanup = cleanup,
95 	.max_runtime = 300,
96 	.taint_check = TST_TAINT_W | TST_TAINT_D,
97 	.needs_kconfigs = (const char *[]) {
98 		"CONFIG_USER_NS=y",
99 		"CONFIG_NET_NS=y",
100 		NULL
101 	},
102 	.save_restore = (const struct tst_path_val[]) {
103 		{"/proc/sys/user/max_user_namespaces", "1024", TST_SR_SKIP},
104 		{}
105 	},
106 	.tags = (const struct tst_tag[]) {
107 		{"linux-git", "15fe076edea7"},
108 		{"CVE", "2018-18559"},
109 		{}
110 	}
111 };
112