Message ID | 20200414154206.21237-1-mdoucha@suse.cz |
---|---|
State | Superseded |
Headers | show |
Series | Add test for CVE 2018-9568 | expand |
Hi! > +/* > + * Copyright (C) 2017 Christoph Paasch <cpaasch@apple.com> > + * Copyright (C) 2020 SUSE LLC <mdoucha@suse.cz> > + * > + * CVE-2018-9568 > + * > + * Test that connect() to AF_UNSPEC address correctly converts IPV6 socket > + * to IPV4 listen socket when IPV6_ADDRFORM is set to AF_INET. > + * Kernel memory corruption fixed in: > + * > + * commit 9d538fa60bad4f7b23193c89e843797a1cf71ef3 > + * Author: Christoph Paasch <cpaasch@apple.com> > + * Date: Tue Sep 26 17:38:50 2017 -0700 > + * > + * net: Set sk_prot_creator when cloning sockets to the right proto > + */ > + > +#include <sys/types.h> > +#include <sys/socket.h> > +#include <netinet/in.h> > +#include <netinet/tcp.h> > + > +#include "tst_test.h" > +#include "tst_net.h" > +#include "tst_taint.h" > + > +static int listenfd; > +static struct sockaddr_in6 bind_addr; > +static struct sockaddr_in bind_addr4, client_addr; > +static struct sockaddr reset_addr; > + > +static void setup(void) > +{ > + tst_taint_init(TST_TAINT_W | TST_TAINT_D); > + > + tst_init_sockaddr_inet6_bin(&bind_addr, &in6addr_any, 42424); > + tst_init_sockaddr_inet_bin(&bind_addr4, INADDR_ANY, 0); > + tst_init_sockaddr_inet(&client_addr, "127.0.0.1", 42424); Do we have use the hardcoded port here? We do have TST_GET_UNUSED_PORT() that should be used for port allocation. > + memset(&reset_addr, 0, sizeof(reset_addr)); > + reset_addr.sa_family = AF_UNSPEC; > + > + listenfd = SAFE_SOCKET(AF_INET6, SOCK_STREAM, IPPROTO_TCP); > + SAFE_BIND(listenfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); > + SAFE_LISTEN(listenfd, 5); > +} > + > +static void cleanup(void) > +{ > + if (listenfd >= 0) > + SAFE_CLOSE(listenfd); > +} > + > +static void run(void) > +{ > + int i, addrlen, fd, confd1, confd2, confd3; > + struct sockaddr_storage client_addr2; > + > + for (i = 0; i < 1000; i++) { > + confd1 = SAFE_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP); > + SAFE_CONNECT(confd1, (struct sockaddr *)&client_addr, > + sizeof(client_addr)); > + > + fd = SAFE_ACCEPT(listenfd, NULL, NULL); > + SAFE_SETSOCKOPT_INT(fd, SOL_IPV6, IPV6_ADDRFORM, AF_INET); > + SAFE_CONNECT(fd, (struct sockaddr *)&reset_addr, > + sizeof(reset_addr)); > + SAFE_BIND(fd, (struct sockaddr *)&bind_addr4, > + sizeof(bind_addr4)); > + SAFE_LISTEN(fd, 5); > + > + addrlen = tst_get_connect_address(fd, &client_addr2); > + confd2 = SAFE_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP); > + SAFE_CONNECT(confd2, (struct sockaddr *)&client_addr2, addrlen); > + confd3 = SAFE_ACCEPT(fd, NULL, NULL); > + > + SAFE_CLOSE(confd3); > + SAFE_CLOSE(confd2); > + SAFE_CLOSE(confd1); > + SAFE_CLOSE(fd); > + > + if (tst_taint_check()) { > + tst_res(TFAIL, "Kernel is vulnerable"); > + return; > + } > + } > + > + tst_res(TPASS, "Nothing bad happened, probably"); > +} > + > +static struct tst_test test = { > + .test_all = run, > + .setup = setup, > + .cleanup = cleanup, > + .tags = (const struct tst_tag[]) { > + {"linux-git", "9d538fa60bad"}, > + {"CVE", "2018-9568"}, > + {} > + } > +}; > -- > 2.26.0 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp
diff --git a/runtest/cve b/runtest/cve index b26e02f0b..629cf7035 100644 --- a/runtest/cve +++ b/runtest/cve @@ -41,6 +41,7 @@ cve-2017-18075 pcrypt_aead01 cve-2017-1000380 snd_timer01 cve-2018-5803 sctp_big_chunk cve-2018-7566 snd_seq01 +cve-2018-9568 connect02 cve-2018-1000001 realpath01 cve-2018-1000199 ptrace08 cve-2018-1000204 ioctl_sg01 diff --git a/runtest/syscalls b/runtest/syscalls index 44254d7da..2b85473ba 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -121,6 +121,7 @@ close08 close08 confstr01 confstr01 connect01 connect01 +connect02 connect02 creat01 creat01 creat03 creat03 diff --git a/testcases/kernel/syscalls/connect/.gitignore b/testcases/kernel/syscalls/connect/.gitignore index b425169a8..0a3fc90bf 100644 --- a/testcases/kernel/syscalls/connect/.gitignore +++ b/testcases/kernel/syscalls/connect/.gitignore @@ -1 +1,2 @@ /connect01 +/connect02 diff --git a/testcases/kernel/syscalls/connect/connect02.c b/testcases/kernel/syscalls/connect/connect02.c new file mode 100644 index 000000000..141f83dc2 --- /dev/null +++ b/testcases/kernel/syscalls/connect/connect02.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Christoph Paasch <cpaasch@apple.com> + * Copyright (C) 2020 SUSE LLC <mdoucha@suse.cz> + * + * CVE-2018-9568 + * + * Test that connect() to AF_UNSPEC address correctly converts IPV6 socket + * to IPV4 listen socket when IPV6_ADDRFORM is set to AF_INET. + * Kernel memory corruption fixed in: + * + * commit 9d538fa60bad4f7b23193c89e843797a1cf71ef3 + * Author: Christoph Paasch <cpaasch@apple.com> + * Date: Tue Sep 26 17:38:50 2017 -0700 + * + * net: Set sk_prot_creator when cloning sockets to the right proto + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> + +#include "tst_test.h" +#include "tst_net.h" +#include "tst_taint.h" + +static int listenfd; +static struct sockaddr_in6 bind_addr; +static struct sockaddr_in bind_addr4, client_addr; +static struct sockaddr reset_addr; + +static void setup(void) +{ + tst_taint_init(TST_TAINT_W | TST_TAINT_D); + + tst_init_sockaddr_inet6_bin(&bind_addr, &in6addr_any, 42424); + tst_init_sockaddr_inet_bin(&bind_addr4, INADDR_ANY, 0); + tst_init_sockaddr_inet(&client_addr, "127.0.0.1", 42424); + memset(&reset_addr, 0, sizeof(reset_addr)); + reset_addr.sa_family = AF_UNSPEC; + + listenfd = SAFE_SOCKET(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + SAFE_BIND(listenfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); + SAFE_LISTEN(listenfd, 5); +} + +static void cleanup(void) +{ + if (listenfd >= 0) + SAFE_CLOSE(listenfd); +} + +static void run(void) +{ + int i, addrlen, fd, confd1, confd2, confd3; + struct sockaddr_storage client_addr2; + + for (i = 0; i < 1000; i++) { + confd1 = SAFE_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP); + SAFE_CONNECT(confd1, (struct sockaddr *)&client_addr, + sizeof(client_addr)); + + fd = SAFE_ACCEPT(listenfd, NULL, NULL); + SAFE_SETSOCKOPT_INT(fd, SOL_IPV6, IPV6_ADDRFORM, AF_INET); + SAFE_CONNECT(fd, (struct sockaddr *)&reset_addr, + sizeof(reset_addr)); + SAFE_BIND(fd, (struct sockaddr *)&bind_addr4, + sizeof(bind_addr4)); + SAFE_LISTEN(fd, 5); + + addrlen = tst_get_connect_address(fd, &client_addr2); + confd2 = SAFE_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP); + SAFE_CONNECT(confd2, (struct sockaddr *)&client_addr2, addrlen); + confd3 = SAFE_ACCEPT(fd, NULL, NULL); + + SAFE_CLOSE(confd3); + SAFE_CLOSE(confd2); + SAFE_CLOSE(confd1); + SAFE_CLOSE(fd); + + if (tst_taint_check()) { + tst_res(TFAIL, "Kernel is vulnerable"); + return; + } + } + + tst_res(TPASS, "Nothing bad happened, probably"); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .tags = (const struct tst_tag[]) { + {"linux-git", "9d538fa60bad"}, + {"CVE", "2018-9568"}, + {} + } +};
Fixes #438 Signed-off-by: Martin Doucha <mdoucha@suse.cz> --- runtest/cve | 1 + runtest/syscalls | 1 + testcases/kernel/syscalls/connect/.gitignore | 1 + testcases/kernel/syscalls/connect/connect02.c | 100 ++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 testcases/kernel/syscalls/connect/connect02.c