All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 0/3] Add Netlink and Crypto libraries, plus pcrypt_aead01
@ 2018-03-21 14:39 Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 1/3] lib: Check received message was not truncated Richard Palethorpe
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Richard Palethorpe @ 2018-03-21 14:39 UTC (permalink / raw)
  To: ltp

This adds two new libraries containing the minimum functionality needed for
the test pcrypt_aead01 which I previously posted as CVE-2017-18075.

Richard Palethorpe (3):
  lib: Check received message was not truncated
  lib: Add tst_crypto and tst_netlink libs
  Add pcrypt_aead01 CVE-2017-18075

 include/tst_crypto.h                    | 135 ++++++++++++++++++++++++++++++++
 include/tst_netlink.h                   |  63 +++++++++++++++
 include/tst_netlink_fn.h                |  35 +++++++++
 lib/safe_net.c                          |  13 ++-
 lib/tst_crypto.c                        | 122 +++++++++++++++++++++++++++++
 lib/tst_netlink.c                       |  63 +++++++++++++++
 runtest/crypto                          |   1 +
 runtest/cve                             |   1 +
 testcases/kernel/crypto/.gitignore      |   1 +
 testcases/kernel/crypto/Makefile        |  22 ++++++
 testcases/kernel/crypto/pcrypt_aead01.c |  85 ++++++++++++++++++++
 11 files changed, 540 insertions(+), 1 deletion(-)
 create mode 100644 include/tst_crypto.h
 create mode 100644 include/tst_netlink.h
 create mode 100644 include/tst_netlink_fn.h
 create mode 100644 lib/tst_crypto.c
 create mode 100644 lib/tst_netlink.c
 create mode 100644 runtest/crypto
 create mode 100644 testcases/kernel/crypto/.gitignore
 create mode 100644 testcases/kernel/crypto/Makefile
 create mode 100644 testcases/kernel/crypto/pcrypt_aead01.c

-- 
2.16.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [LTP] [PATCH v2 1/3] lib: Check received message was not truncated
  2018-03-21 14:39 [LTP] [PATCH v2 0/3] Add Netlink and Crypto libraries, plus pcrypt_aead01 Richard Palethorpe
@ 2018-03-21 14:39 ` Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 3/3] Add pcrypt_aead01 CVE-2017-18075 Richard Palethorpe
  2 siblings, 0 replies; 5+ messages in thread
From: Richard Palethorpe @ 2018-03-21 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
 lib/safe_net.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lib/safe_net.c b/lib/safe_net.c
index 64e2cbcf6..ba38fc08e 100644
--- a/lib/safe_net.c
+++ b/lib/safe_net.c
@@ -240,8 +240,19 @@ ssize_t safe_recvmsg(const char *file, const int lineno, size_t len,
 			 file, lineno, sockfd, msg, flags, rval, len);
 	}
 
-	return rval;
+	if (msg->msg_flags & MSG_TRUNC) {
+		tst_brkm(TBROK, NULL,
+			 "%s:%d: recvmsg(%d, %p, %d): buffer is too small",
+			 file, lineno, sockfd, msg, flags);
+	}
 
+	if (msg->msg_flags & MSG_CTRUNC) {
+		tst_brkm(TBROK, NULL,
+			 "%s:%d: recvmsg(%d, %p, %d): control buffer is too small",
+			 file, lineno, sockfd, msg, flags);
+	}
+
+	return rval;
 }
 
 int safe_bind(const char *file, const int lineno, void (cleanup_fn)(void),
-- 
2.16.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs
  2018-03-21 14:39 [LTP] [PATCH v2 0/3] Add Netlink and Crypto libraries, plus pcrypt_aead01 Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 1/3] lib: Check received message was not truncated Richard Palethorpe
@ 2018-03-21 14:39 ` Richard Palethorpe
  2018-04-06 12:20   ` Cyril Hrubis
  2018-03-21 14:39 ` [LTP] [PATCH v2 3/3] Add pcrypt_aead01 CVE-2017-18075 Richard Palethorpe
  2 siblings, 1 reply; 5+ messages in thread
From: Richard Palethorpe @ 2018-03-21 14:39 UTC (permalink / raw)
  To: ltp

Add some helper functions for dealing with the crypto subsystem.

Signed-off-by: Richard Palethorpe <richiejp@f-m.fm>
---
 include/tst_crypto.h     | 135 +++++++++++++++++++++++++++++++++++++++++++++++
 include/tst_netlink.h    |  63 ++++++++++++++++++++++
 include/tst_netlink_fn.h |  35 ++++++++++++
 lib/tst_crypto.c         | 122 ++++++++++++++++++++++++++++++++++++++++++
 lib/tst_netlink.c        |  63 ++++++++++++++++++++++
 5 files changed, 418 insertions(+)
 create mode 100644 include/tst_crypto.h
 create mode 100644 include/tst_netlink.h
 create mode 100644 include/tst_netlink_fn.h
 create mode 100644 lib/tst_crypto.c
 create mode 100644 lib/tst_netlink.c

diff --git a/include/tst_crypto.h b/include/tst_crypto.h
new file mode 100644
index 000000000..3ed4a81f1
--- /dev/null
+++ b/include/tst_crypto.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * 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/>.
+ */
+
+#ifndef TST_CRYPTO_H
+#define TST_CRYPTO_H
+
+/* Taken from linux/crypto.h */
+#define CRYPTO_MAX_ALG_NAME		64
+#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
+
+#define CRYPTO_ALG_TYPE_MASK		0x0000000f
+#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
+#define CRYPTO_ALG_TYPE_COMPRESS	0x00000002
+#define CRYPTO_ALG_TYPE_AEAD		0x00000003
+#define CRYPTO_ALG_TYPE_BLKCIPHER	0x00000004
+#define CRYPTO_ALG_TYPE_ABLKCIPHER	0x00000005
+#define CRYPTO_ALG_TYPE_SKCIPHER	0x00000005
+#define CRYPTO_ALG_TYPE_GIVCIPHER	0x00000006
+#define CRYPTO_ALG_TYPE_KPP		0x00000008
+#define CRYPTO_ALG_TYPE_ACOMPRESS	0x0000000a
+#define CRYPTO_ALG_TYPE_SCOMPRESS	0x0000000b
+#define CRYPTO_ALG_TYPE_RNG		0x0000000c
+#define CRYPTO_ALG_TYPE_AKCIPHER	0x0000000d
+#define CRYPTO_ALG_TYPE_DIGEST		0x0000000e
+#define CRYPTO_ALG_TYPE_HASH		0x0000000e
+#define CRYPTO_ALG_TYPE_SHASH		0x0000000e
+#define CRYPTO_ALG_TYPE_AHASH		0x0000000f
+
+#define CRYPTO_ALG_TYPE_HASH_MASK	0x0000000e
+#define CRYPTO_ALG_TYPE_AHASH_MASK	0x0000000e
+#define CRYPTO_ALG_TYPE_BLKCIPHER_MASK	0x0000000c
+#define CRYPTO_ALG_TYPE_ACOMPRESS_MASK	0x0000000e
+
+/* Taken from linux/uapi/crypto_user.h */
+enum {
+	CRYPTO_MSG_BASE = 0x10,
+	CRYPTO_MSG_NEWALG = 0x10,
+	CRYPTO_MSG_DELALG,
+	CRYPTO_MSG_UPDATEALG,
+	CRYPTO_MSG_GETALG,
+	CRYPTO_MSG_DELRNG,
+	__CRYPTO_MSG_MAX
+};
+
+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;
+};
+
+/**
+ * struct tst_crypto_session
+ * @fd: File descriptor for the netlink socket.
+ * @seq_num: A sequence number used to identify responses from the kernel.
+ *
+ * Holds state relevant to a netlink crypto connection. The @seq_num is used
+ * to tag each message sent to the netlink layer and is automatically
+ * incremented by the tst_crypto_ functions. When the netlink layer sends a
+ * response (ack) it will use the sequences number from the request.
+ */
+struct tst_crypto_session {
+	int fd;
+	uint32_t seq_num;
+};
+
+/**
+ * tst_crypto_open()
+ * @ses: Session structure to use, it can be uninitialized.
+ *
+ * Creates a crypto session. If some necessary feature is missing then it will
+ * call tst_brk() with %TCONF, for any other error it will use %TBROK.
+ */
+void tst_crypto_open(struct tst_crypto_session *ses);
+
+/**
+ * tst_crypto_close()
+ * @ses: The session to close.
+ */
+void tst_crypto_close(struct tst_crypto_session *ses);
+
+/**
+ * tst_crypto_add_alg()
+ * @ses: An open session.
+ * @alg: The crypto algorithm or module to add.
+ *
+ * This requests a new crypto algorithm/engine/module to be initialized by the
+ * kernel. It sends the request contained in @alg and then waits for a
+ * response. If sending the message or receiving the ack fails at the netlink
+ * level then tst_brk() with %TBROK will be called.
+ *
+ * Return: On success it will return 0 otherwise it will return an inverted
+ *         error code from the crypto layer. If the type of encryption you want
+ *         is not configured then the crypto layer will probably return %ENOENT.
+ */
+int tst_crypto_add_alg(struct tst_crypto_session *ses,
+		       const struct crypto_user_alg *alg);
+
+/**
+ * tst_crypto_del_alg()
+ * @ses: An open session.
+ * @alg: The crypto algorithm to delete.
+ * @retries: How many times the request should be repeated if %EBUSY is returned.
+ *           It can be set to zero for no retries.
+ *
+ * Request that the kernel remove an existing crypto algorithm. This behaves
+ * in a similar way to tst_crypto_add_alg() except that it is the inverse
+ * operation and that it is not unusual for this to return %EBUSY. To avoid
+ * needing to deal with %EBUSY you can set the retries to an appropriate value
+ * like 1000.
+ *
+ * Return: Either 0 or an inverted error code from the crypto layer.
+ */
+int tst_crypto_del_alg(struct tst_crypto_session *ses,
+		       const struct crypto_user_alg *alg,
+		       unsigned int retries);
+
+#endif	/* TST_CRYPTO_H */
diff --git a/include/tst_netlink.h b/include/tst_netlink.h
new file mode 100644
index 000000000..8349644cc
--- /dev/null
+++ b/include/tst_netlink.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * 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/>.
+ */
+
+#ifndef TST_NETLINK_H
+#define TST_NETLINK_H
+
+#include "tst_netlink_fn.h"
+
+/**
+ * SAFE_NETLINK_SEND() / tst_safe_netlink_send()
+ * @fd: netlink socket file descriptor.
+ * @nl_header: netlink header structure describing the message.
+ * @payload: an opaque object containing the message data.
+ * @payload_len: the @payload length only.
+ *
+ * Sends a netlink message using safe_sendmsg(). You should set the message
+ * type and flags to appropriate values within the @nl_header object. However
+ * you do not need to set the message length within @nl_header
+ * (nlmsg_len), if you do it will be overwritten.
+ *
+ * Netlink messages must be aligned correctly which may require padding. This
+ * function will add padding if necessary so that you do not need to pad the
+ * payload or header structure.
+ *
+ * See lib/tst_crypto.c for an example.
+ *
+ * Return: The number of bytes sent.
+ */
+#define SAFE_NETLINK_SEND(fd, nl_header, payload, payload_len)		\
+	tst_safe_netlink_send(__FILE__, __LINE__,			\
+			      fd, nl_header, payload, payload_len)
+
+/**
+ * SAFE_NETLINK_RECV() / tst_safe_netlink()
+ * @fd: netlink socket file descriptor.
+ * @nl_header_buf: buffer to contain the received netlink header structure.
+ * @buf_len: The length of the header buffer. In general this should be
+ * 	     at at least the page size.
+ *
+ * Receives one or more netlink messages using safe_recvmsg().
+ *
+ * See lib/tst_crypto.c for an example.
+ *
+ * Return: The number of bytes received.
+ */
+#define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len)			\
+	tst_safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len)
+
+#endif /* TST_NETLINK_H */
diff --git a/include/tst_netlink_fn.h b/include/tst_netlink_fn.h
new file mode 100644
index 000000000..9aaad7091
--- /dev/null
+++ b/include/tst_netlink_fn.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * 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/>.
+ */
+
+#ifndef TST_NETLINK_FN_H
+#define TST_NETLINK_FN_H
+
+#include <linux/netlink.h>
+
+#ifndef NETLINK_CRYPTO
+#define NETLINK_CRYPTO 21
+#endif
+
+ssize_t tst_safe_netlink_send(const char *file, const int lineno,
+			      int fd, struct nlmsghdr *nh,
+			      const void *payload, int payload_len);
+
+ssize_t tst_safe_netlink_recv(const char *file, const int lineno,
+			      int fd, char *nl_headers_buf,
+			      size_t buf_len);
+
+#endif	/* TST_NETLINK_FN_H */
diff --git a/lib/tst_crypto.c b/lib/tst_crypto.c
new file mode 100644
index 000000000..dbe7f32b7
--- /dev/null
+++ b/lib/tst_crypto.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
+ *                    Nicolai Stange <nstange@suse.de>
+ *
+ * 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/>.
+ */
+
+#include <errno.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_crypto.h"
+#include "tst_netlink.h"
+
+#define RETRY_DELAY_NSEC 1000000 /* For operations which can fail with EBUSY. */
+
+void tst_crypto_open(struct tst_crypto_session *ses)
+{
+	TEST(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO));
+	if (TEST_RETURN < 0 && TEST_ERRNO == EPROTONOSUPPORT) {
+		tst_res(TCONF | TTERRNO, "NETLINK_CRYPTO is probably disabled");
+	} else if (TEST_RETURN < 0) {
+		tst_brk(TBROK | TTERRNO,
+			"socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
+	}
+
+	ses->fd = TEST_RETURN;
+	ses->seq_num = 0;
+}
+
+void tst_crypto_close(struct tst_crypto_session *ses)
+{
+	SAFE_CLOSE(ses->fd);
+}
+
+static int tst_crypto_recv_ack(struct tst_crypto_session *ses)
+{
+	int len;
+	char buf[8196];
+	struct nlmsghdr *nh;
+
+	len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf));
+
+	for (nh = (struct nlmsghdr *) buf;
+	     NLMSG_OK(nh, len);
+	     nh = NLMSG_NEXT(nh, len)) {
+		if (nh->nlmsg_seq != ses->seq_num) {
+			tst_brk(TBROK,
+				"Message out of sequence; type=0%hx, seq_num=%u (not %u)",
+				nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num);
+		}
+
+		/* Acks use the error message type with error number set to
+		 * zero. Ofcourse we could also receive an actual error.
+		 */
+		if (nh->nlmsg_type == NLMSG_ERROR)
+			return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
+
+		tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u",
+			nh->nlmsg_type, nh->nlmsg_seq);
+	}
+
+	tst_brk(TBROK, "Empty message from netlink socket?");
+
+	return 0;
+}
+
+int tst_crypto_add_alg(struct tst_crypto_session *ses,
+		       const struct crypto_user_alg *alg)
+{
+	struct nlmsghdr nh = {
+		.nlmsg_type = CRYPTO_MSG_NEWALG,
+		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+		.nlmsg_seq = ++(ses->seq_num),
+		.nlmsg_pid = 0,
+	};
+
+	SAFE_NETLINK_SEND(ses->fd, &nh, alg, sizeof(*alg));
+
+	return tst_crypto_recv_ack(ses);
+}
+
+int tst_crypto_del_alg(struct tst_crypto_session *ses,
+		       const struct crypto_user_alg *alg,
+		       unsigned int retries)
+{
+	unsigned int i = 0;
+	struct timespec delay = { .tv_nsec = RETRY_DELAY_NSEC };
+	struct nlmsghdr nh = {
+		.nlmsg_type = CRYPTO_MSG_DELALG,
+		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+		.nlmsg_pid = 0,
+	};
+
+	while (1) {
+		nh.nlmsg_seq = ++(ses->seq_num);
+
+		SAFE_NETLINK_SEND(ses->fd, &nh, alg, sizeof(*alg));
+
+		TEST(tst_crypto_recv_ack(ses));
+		if (TEST_RETURN != -EBUSY || i >= retries)
+			break;
+
+		if (nanosleep(&delay, NULL) && errno != EINTR)
+			tst_brk(TBROK | TERRNO, "nanosleep");
+
+		++i;
+	}
+
+	return TEST_RETURN;
+}
diff --git a/lib/tst_netlink.c b/lib/tst_netlink.c
new file mode 100644
index 000000000..d7ec7adac
--- /dev/null
+++ b/lib/tst_netlink.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
+ *                    Nicolai Stange <nstange@suse.de>
+ *
+ * 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/>.
+ */
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_safe_net.h"
+#include "tst_netlink.h"
+#include "tst_common.h"
+
+ssize_t tst_safe_netlink_send(const char *file, const int lineno,
+			      int fd, struct nlmsghdr *nh,
+			      const void *payload, int payload_len)
+{
+	static char padding[NLMSG_ALIGNTO];
+	struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
+	struct iovec iov[4] = {
+		{nh, sizeof(*nh)},
+		{padding, NLMSG_HDRLEN - sizeof(*nh)},
+		{(void *)payload, payload_len},
+		{padding, NLMSG_ALIGN(payload_len) - payload_len},
+	};
+	struct msghdr msg = {
+		.msg_name = &sa,
+		.msg_namelen = sizeof(sa),
+		.msg_iov = iov,
+		.msg_iovlen = ARRAY_SIZE(iov),
+	};
+
+	nh->nlmsg_len = NLMSG_LENGTH(payload_len);
+
+	return safe_sendmsg(file, lineno,
+			    NLMSG_ALIGN(nh->nlmsg_len), fd, &msg, 0);
+}
+
+ssize_t tst_safe_netlink_recv(const char *file, const int lineno,
+			      int fd, char *nl_headers_buf, size_t buf_len)
+{
+	struct iovec iov = { nl_headers_buf, buf_len };
+	struct sockaddr_nl sa;
+	struct msghdr msg = {
+		.msg_name = &sa,
+		.msg_namelen = sizeof(sa),
+		.msg_iov = &iov,
+		.msg_iovlen = 1
+	};
+
+	return safe_recvmsg(file, lineno, 0, fd, &msg, 0);
+}
+
-- 
2.16.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [LTP] [PATCH v2 3/3] Add pcrypt_aead01 CVE-2017-18075
  2018-03-21 14:39 [LTP] [PATCH v2 0/3] Add Netlink and Crypto libraries, plus pcrypt_aead01 Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 1/3] lib: Check received message was not truncated Richard Palethorpe
  2018-03-21 14:39 ` [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs Richard Palethorpe
@ 2018-03-21 14:39 ` Richard Palethorpe
  2 siblings, 0 replies; 5+ messages in thread
From: Richard Palethorpe @ 2018-03-21 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
 runtest/crypto                          |  1 +
 runtest/cve                             |  1 +
 testcases/kernel/crypto/.gitignore      |  1 +
 testcases/kernel/crypto/Makefile        | 22 +++++++++
 testcases/kernel/crypto/pcrypt_aead01.c | 85 +++++++++++++++++++++++++++++++++
 5 files changed, 110 insertions(+)
 create mode 100644 runtest/crypto
 create mode 100644 testcases/kernel/crypto/.gitignore
 create mode 100644 testcases/kernel/crypto/Makefile
 create mode 100644 testcases/kernel/crypto/pcrypt_aead01.c

diff --git a/runtest/crypto b/runtest/crypto
new file mode 100644
index 000000000..e5ba61e5e
--- /dev/null
+++ b/runtest/crypto
@@ -0,0 +1 @@
+pcrypt_aead01 pcrypt_aead01
diff --git a/runtest/cve b/runtest/cve
index 8b7cbe539..15fa02bc8 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 pcrypt_aead01
diff --git a/testcases/kernel/crypto/.gitignore b/testcases/kernel/crypto/.gitignore
new file mode 100644
index 000000000..fafe5c972
--- /dev/null
+++ b/testcases/kernel/crypto/.gitignore
@@ -0,0 +1 @@
+pcrypt_aead01
diff --git a/testcases/kernel/crypto/Makefile b/testcases/kernel/crypto/Makefile
new file mode 100644
index 000000000..76f9308c2
--- /dev/null
+++ b/testcases/kernel/crypto/Makefile
@@ -0,0 +1,22 @@
+# Copyright (c) 2017 Linux Test Project
+#
+# 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 would 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/>.
+
+top_srcdir		?= ../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+CFLAGS			+= -D_GNU_SOURCE
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/crypto/pcrypt_aead01.c b/testcases/kernel/crypto/pcrypt_aead01.c
new file mode 100644
index 000000000..8053b33e4
--- /dev/null
+++ b/testcases/kernel/crypto/pcrypt_aead01.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 SUSE
+ * Author: Nicolai Stange <nstange@suse.de>
+ * LTP conversion: Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * Originally found by syzkaller:
+ * https://groups.google.com/forum/#!topic/syzkaller-bugs/NKn_ivoPOpk
+ *
+ * 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.
+ *
+ * The test works by adding and then removing pcrypt-AEAD instances.
+ * See commit d76c68109f37 crypto: pcrypt - fix freeing pcrypt instances.
+ *
+ * If the bug is present then this will probably crash the kernel, but also
+ * sometimes the test simply times out.
+ */
+
+#include <errno.h>
+#include <time.h>
+
+#include "tst_test.h"
+#include "tst_safe_net.h"
+#include "tst_taint.h"
+#include "tst_crypto.h"
+
+#define ATTEMPTS 10000
+#define DEL_RETRY_COUNT 1000
+
+static struct tst_crypto_session ses;
+
+void setup(void)
+{
+	tst_crypto_open(&ses);
+}
+
+void run(void)
+{
+	int 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,
+	};
+
+	for (i = 0; i < ATTEMPTS; ++i) {
+		TEST(tst_crypto_add_alg(&ses, &a));
+		if (TEST_RETURN && TEST_RETURN == -ENOENT) {
+			tst_brk(TCONF | TRERRNO,
+				"pcrypt, hmac, sha256, cbc or aes not supported");
+		}
+		if (TEST_RETURN && TEST_RETURN != -EEXIST)
+			tst_brk(TBROK | TRERRNO, "add_alg");
+
+		TEST(tst_crypto_del_alg(&ses, &a, DEL_RETRY_COUNT));
+		if (TEST_RETURN)
+			tst_brk(TBROK | TRERRNO, "del_alg");
+	}
+
+	tst_res(TPASS, "Nothing bad appears to have happened");
+}
+
+void cleanup(void)
+{
+	tst_crypto_close(&ses);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = run,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
-- 
2.16.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs
  2018-03-21 14:39 ` [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs Richard Palethorpe
@ 2018-04-06 12:20   ` Cyril Hrubis
  0 siblings, 0 replies; 5+ messages in thread
From: Cyril Hrubis @ 2018-04-06 12:20 UTC (permalink / raw)
  To: ltp

Hi!
> ---
>  include/tst_crypto.h     | 135 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/tst_netlink.h    |  63 ++++++++++++++++++++++
>  include/tst_netlink_fn.h |  35 ++++++++++++
>  lib/tst_crypto.c         | 122 ++++++++++++++++++++++++++++++++++++++++++
>  lib/tst_netlink.c        |  63 ++++++++++++++++++++++

Is there a reason to split the netlink header into two?

We do that for safe_macros that are used both by the old library and the
new library where the split is easier than ifdefing all the macro
definitions to choose between newlib and oldlib...

And given that the netlink functions are simple wrappers that only
pack/unpack parameters I would be inclined to put them into the header
as static inline functions as well so that we would end up with one
netlink header that combines all the content from tst_netlink.h
tst_netlink_fn.h and tst_netlink.c.

> diff --git a/include/tst_crypto.h b/include/tst_crypto.h
> new file mode 100644
> index 000000000..3ed4a81f1
> --- /dev/null
> +++ b/include/tst_crypto.h
> @@ -0,0 +1,135 @@
> +/*
> + * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
> + *
> + * 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/>.
> + */
> +
> +#ifndef TST_CRYPTO_H
> +#define TST_CRYPTO_H
> +
> +/* Taken from linux/crypto.h */
> +#define CRYPTO_MAX_ALG_NAME		64
> +#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
> +
> +#define CRYPTO_ALG_TYPE_MASK		0x0000000f
> +#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
> +#define CRYPTO_ALG_TYPE_COMPRESS	0x00000002
> +#define CRYPTO_ALG_TYPE_AEAD		0x00000003
> +#define CRYPTO_ALG_TYPE_BLKCIPHER	0x00000004
> +#define CRYPTO_ALG_TYPE_ABLKCIPHER	0x00000005
> +#define CRYPTO_ALG_TYPE_SKCIPHER	0x00000005
> +#define CRYPTO_ALG_TYPE_GIVCIPHER	0x00000006
> +#define CRYPTO_ALG_TYPE_KPP		0x00000008
> +#define CRYPTO_ALG_TYPE_ACOMPRESS	0x0000000a
> +#define CRYPTO_ALG_TYPE_SCOMPRESS	0x0000000b
> +#define CRYPTO_ALG_TYPE_RNG		0x0000000c
> +#define CRYPTO_ALG_TYPE_AKCIPHER	0x0000000d
> +#define CRYPTO_ALG_TYPE_DIGEST		0x0000000e
> +#define CRYPTO_ALG_TYPE_HASH		0x0000000e
> +#define CRYPTO_ALG_TYPE_SHASH		0x0000000e
> +#define CRYPTO_ALG_TYPE_AHASH		0x0000000f
> +
> +#define CRYPTO_ALG_TYPE_HASH_MASK	0x0000000e
> +#define CRYPTO_ALG_TYPE_AHASH_MASK	0x0000000e
> +#define CRYPTO_ALG_TYPE_BLKCIPHER_MASK	0x0000000c
> +#define CRYPTO_ALG_TYPE_ACOMPRESS_MASK	0x0000000e
> +
> +/* Taken from linux/uapi/crypto_user.h */
> +enum {
> +	CRYPTO_MSG_BASE = 0x10,
> +	CRYPTO_MSG_NEWALG = 0x10,
> +	CRYPTO_MSG_DELALG,
> +	CRYPTO_MSG_UPDATEALG,
> +	CRYPTO_MSG_GETALG,
> +	CRYPTO_MSG_DELRNG,
> +	__CRYPTO_MSG_MAX
> +};
> +
> +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;
> +};
> +
> +/**
> + * struct tst_crypto_session
> + * @fd: File descriptor for the netlink socket.
> + * @seq_num: A sequence number used to identify responses from the kernel.
> + *
> + * Holds state relevant to a netlink crypto connection. The @seq_num is used
> + * to tag each message sent to the netlink layer and is automatically
> + * incremented by the tst_crypto_ functions. When the netlink layer sends a
> + * response (ack) it will use the sequences number from the request.
> + */
> +struct tst_crypto_session {
> +	int fd;
> +	uint32_t seq_num;
> +};

These definitions would be probably better to be put into lapi/crypto.h
and we have a rule to use the system defined ones whenever possible, it
looks like we can make use of the CRYPTO_MSG_* and crylto_user_alg from
the /usr/include/linux/cryptouser.h.


> +/**
> + * tst_crypto_open()
> + * @ses: Session structure to use, it can be uninitialized.
> + *
> + * Creates a crypto session. If some necessary feature is missing then it will
> + * call tst_brk() with %TCONF, for any other error it will use %TBROK.
> + */
> +void tst_crypto_open(struct tst_crypto_session *ses);
> +
> +/**
> + * tst_crypto_close()
> + * @ses: The session to close.
> + */
> +void tst_crypto_close(struct tst_crypto_session *ses);
> +
> +/**
> + * tst_crypto_add_alg()
> + * @ses: An open session.
> + * @alg: The crypto algorithm or module to add.
> + *
> + * This requests a new crypto algorithm/engine/module to be initialized by the
> + * kernel. It sends the request contained in @alg and then waits for a
> + * response. If sending the message or receiving the ack fails at the netlink
> + * level then tst_brk() with %TBROK will be called.
> + *
> + * Return: On success it will return 0 otherwise it will return an inverted
> + *         error code from the crypto layer. If the type of encryption you want
> + *         is not configured then the crypto layer will probably return %ENOENT.
> + */
> +int tst_crypto_add_alg(struct tst_crypto_session *ses,
> +		       const struct crypto_user_alg *alg);
> +
> +/**
> + * tst_crypto_del_alg()
> + * @ses: An open session.
> + * @alg: The crypto algorithm to delete.
> + * @retries: How many times the request should be repeated if %EBUSY is returned.
> + *           It can be set to zero for no retries.
> + *
> + * Request that the kernel remove an existing crypto algorithm. This behaves
> + * in a similar way to tst_crypto_add_alg() except that it is the inverse
> + * operation and that it is not unusual for this to return %EBUSY. To avoid
> + * needing to deal with %EBUSY you can set the retries to an appropriate value
> + * like 1000.
> + *
> + * Return: Either 0 or an inverted error code from the crypto layer.
> + */
> +int tst_crypto_del_alg(struct tst_crypto_session *ses,
> +		       const struct crypto_user_alg *alg,
> +		       unsigned int retries);


Do we really need to expose the retries here to the user of the library?
I do not like when we have random constants hardcoded all over the
codebase...

> +#endif	/* TST_CRYPTO_H */
> diff --git a/include/tst_netlink.h b/include/tst_netlink.h
> new file mode 100644
> index 000000000..8349644cc
> --- /dev/null
> +++ b/include/tst_netlink.h
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
> + *
> + * 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/>.
> + */
> +
> +#ifndef TST_NETLINK_H
> +#define TST_NETLINK_H
> +
> +#include "tst_netlink_fn.h"
> +
> +/**
> + * SAFE_NETLINK_SEND() / tst_safe_netlink_send()
> + * @fd: netlink socket file descriptor.
> + * @nl_header: netlink header structure describing the message.
> + * @payload: an opaque object containing the message data.
> + * @payload_len: the @payload length only.
> + *
> + * Sends a netlink message using safe_sendmsg(). You should set the message
> + * type and flags to appropriate values within the @nl_header object. However
> + * you do not need to set the message length within @nl_header
> + * (nlmsg_len), if you do it will be overwritten.
> + *
> + * Netlink messages must be aligned correctly which may require padding. This
> + * function will add padding if necessary so that you do not need to pad the
> + * payload or header structure.
> + *
> + * See lib/tst_crypto.c for an example.
> + *
> + * Return: The number of bytes sent.
> + */
> +#define SAFE_NETLINK_SEND(fd, nl_header, payload, payload_len)		\
> +	tst_safe_netlink_send(__FILE__, __LINE__,			\
> +			      fd, nl_header, payload, payload_len)

Given that the safe_ prefix is used all over the library we can drop the
tst_ prefix from the function names here, and maybe update documentation
that safe_ prefix is reserved for the test library as well...

...

> diff --git a/lib/tst_crypto.c b/lib/tst_crypto.c
> new file mode 100644
> index 000000000..dbe7f32b7
> --- /dev/null
> +++ b/lib/tst_crypto.c
> @@ -0,0 +1,122 @@
> +/*
> + * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
> + *                    Nicolai Stange <nstange@suse.de>
> + *
> + * 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/>.
> + */
> +
> +#include <errno.h>
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_crypto.h"
> +#include "tst_netlink.h"
> +
> +#define RETRY_DELAY_NSEC 1000000 /* For operations which can fail with EBUSY. */
> +
> +void tst_crypto_open(struct tst_crypto_session *ses)
> +{
> +	TEST(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO));
> +	if (TEST_RETURN < 0 && TEST_ERRNO == EPROTONOSUPPORT) {
> +		tst_res(TCONF | TTERRNO, "NETLINK_CRYPTO is probably disabled");
                    ^
		The comment in the header says that it will tst_brk()
		here, or am I mistaken?

> +	} else if (TEST_RETURN < 0) {
> +		tst_brk(TBROK | TTERRNO,
> +			"socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
> +	}
> +
> +	ses->fd = TEST_RETURN;
> +	ses->seq_num = 0;
> +}
> +
> +void tst_crypto_close(struct tst_crypto_session *ses)
> +{
> +	SAFE_CLOSE(ses->fd);
> +}
> +
> +static int tst_crypto_recv_ack(struct tst_crypto_session *ses)
> +{
> +	int len;
> +	char buf[8196];
> +	struct nlmsghdr *nh;
> +
> +	len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf));
> +
> +	for (nh = (struct nlmsghdr *) buf;
> +	     NLMSG_OK(nh, len);
> +	     nh = NLMSG_NEXT(nh, len)) {
> +		if (nh->nlmsg_seq != ses->seq_num) {
> +			tst_brk(TBROK,
> +				"Message out of sequence; type=0%hx, seq_num=%u (not %u)",
> +				nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num);
> +		}
> +
> +		/* Acks use the error message type with error number set to
> +		 * zero. Ofcourse we could also receive an actual error.
> +		 */
> +		if (nh->nlmsg_type == NLMSG_ERROR)
> +			return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
> +
> +		tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u",
> +			nh->nlmsg_type, nh->nlmsg_seq);
> +	}
> +
> +	tst_brk(TBROK, "Empty message from netlink socket?");
> +
> +	return 0;
          ^

	  Not that it matters, since unless we call this function from
	  test cleanup the tst_brk() will exit the test, but this should
	  be probably non-zero.

> +}
> +
> +int tst_crypto_add_alg(struct tst_crypto_session *ses,
> +		       const struct crypto_user_alg *alg)
> +{
> +	struct nlmsghdr nh = {
> +		.nlmsg_type = CRYPTO_MSG_NEWALG,
> +		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
> +		.nlmsg_seq = ++(ses->seq_num),
> +		.nlmsg_pid = 0,
> +	};
> +
> +	SAFE_NETLINK_SEND(ses->fd, &nh, alg, sizeof(*alg));
> +
> +	return tst_crypto_recv_ack(ses);
> +}
> +
> +int tst_crypto_del_alg(struct tst_crypto_session *ses,
> +		       const struct crypto_user_alg *alg,
> +		       unsigned int retries)
> +{
> +	unsigned int i = 0;
> +	struct timespec delay = { .tv_nsec = RETRY_DELAY_NSEC };
> +	struct nlmsghdr nh = {
> +		.nlmsg_type = CRYPTO_MSG_DELALG,
> +		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
> +		.nlmsg_pid = 0,
> +	};
> +
> +	while (1) {
> +		nh.nlmsg_seq = ++(ses->seq_num);
> +
> +		SAFE_NETLINK_SEND(ses->fd, &nh, alg, sizeof(*alg));
> +
> +		TEST(tst_crypto_recv_ack(ses));
> +		if (TEST_RETURN != -EBUSY || i >= retries)
> +			break;
> +
> +		if (nanosleep(&delay, NULL) && errno != EINTR)
> +			tst_brk(TBROK | TERRNO, "nanosleep");

We may as well do usleep(1) here instead of the nanosleep()

> +		++i;
> +	}
> +
> +	return TEST_RETURN;
> +}

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-04-06 12:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-21 14:39 [LTP] [PATCH v2 0/3] Add Netlink and Crypto libraries, plus pcrypt_aead01 Richard Palethorpe
2018-03-21 14:39 ` [LTP] [PATCH v2 1/3] lib: Check received message was not truncated Richard Palethorpe
2018-03-21 14:39 ` [LTP] [PATCH v2 2/3] lib: Add tst_crypto and tst_netlink libs Richard Palethorpe
2018-04-06 12:20   ` Cyril Hrubis
2018-03-21 14:39 ` [LTP] [PATCH v2 3/3] Add pcrypt_aead01 CVE-2017-18075 Richard Palethorpe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.