• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019 SUSE LLC <mdoucha@suse.cz>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * CVE-2017-1000112
10  *
11  * Check that UDP fragmentation offload doesn't cause memory corruption
12  * if the userspace process turns off UFO in between two send() calls.
13  *
14  * Kernel crash fixed in 4.13
15  * 85f1bd9a7b5a ("udp: consistently apply ufo or fragmentation")
16  */
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <sys/ioctl.h>
22 #include <net/if.h>
23 
24 #include "tst_test.h"
25 #include "tst_net.h"
26 
27 #define BUFSIZE 4000
28 
29 static struct sockaddr_in addr;
30 static int dst_sock = -1;
31 
setup(void)32 static void setup(void)
33 {
34 	struct ifreq ifr;
35 	socklen_t addrlen = sizeof(addr);
36 
37 	tst_setup_netns();
38 
39 	tst_init_sockaddr_inet_bin(&addr, INADDR_LOOPBACK, 0);
40 	dst_sock = SAFE_SOCKET(AF_INET, SOCK_DGRAM, 0);
41 
42 	strcpy(ifr.ifr_name, "lo");
43 	ifr.ifr_mtu = 1500;
44 	SAFE_IOCTL(dst_sock, SIOCSIFMTU, &ifr);
45 	ifr.ifr_flags = IFF_UP;
46 	SAFE_IOCTL(dst_sock, SIOCSIFFLAGS, &ifr);
47 
48 	SAFE_BIND(dst_sock, (struct sockaddr *)&addr, addrlen);
49 	SAFE_GETSOCKNAME(dst_sock, (struct sockaddr*)&addr, &addrlen);
50 }
51 
cleanup(void)52 static void cleanup(void)
53 {
54 	if (dst_sock != -1)
55 		SAFE_CLOSE(dst_sock);
56 }
57 
run(void)58 static void run(void)
59 {
60 	int sock, i;
61 	char buf[BUFSIZE];
62 
63 	memset(buf, 0x42, BUFSIZE);
64 
65 	for (i = 0; i < 1000; i++) {
66 		sock = SAFE_SOCKET(AF_INET, SOCK_DGRAM, 0);
67 		SAFE_CONNECT(sock, (struct sockaddr *)&addr, sizeof(addr));
68 		SAFE_SEND(1, sock, buf, BUFSIZE, MSG_MORE);
69 		SAFE_SETSOCKOPT_INT(sock, SOL_SOCKET, SO_NO_CHECK, 1);
70 		send(sock, buf, 1, 0);
71 		SAFE_CLOSE(sock);
72 
73 		if (tst_taint_check()) {
74 			tst_res(TFAIL, "Kernel is vulnerable");
75 			return;
76 		}
77 	}
78 
79 	tst_res(TPASS, "Nothing bad happened, probably");
80 }
81 
82 static struct tst_test test = {
83 	.test_all = run,
84 	.setup = setup,
85 	.cleanup = cleanup,
86 	.taint_check = TST_TAINT_W | TST_TAINT_D,
87 	.needs_kconfigs = (const char *[]) {
88 		"CONFIG_USER_NS=y",
89 		"CONFIG_NET_NS=y",
90 		NULL
91 	},
92 	.save_restore = (const struct tst_path_val[]) {
93 		{"/proc/sys/user/max_user_namespaces", "1024", TST_SR_SKIP},
94 		{}
95 	},
96 	.tags = (const struct tst_tag[]) {
97 		{"linux-git", "85f1bd9a7b5a"},
98 		{"CVE", "2017-1000112"},
99 		{}
100 	}
101 };
102