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