public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248
@ 2023-11-14 12:31 Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

Let's refactor the rtnetlink helper functions for generic use where possible.
The Netlink context structure can be used for other Netlink protocols like
NETLINK_CRYPTO or NETLINK_NETFILTER. One of the exceptions is
the NETLINK_KOBJECT_UEVENT protocol which returns raw data without the usual
headers.

The first patch replaces the tst_rtnl_* and RTNL_* prefix with tst_netlink_*
and NETLINK_* respectively to signify that the functions can be used
for generic netlink communication. The attribute handling functions are
specific to the NETLINK_ROUTE protocol so they keep the old prefix. The fourth
patch adds new attribute handling functions for generic struct nlattr.

The third patch replaces old netlink send/receive helper functions
with the context-based helpers in crypto test code.

Finally, add test for CVE 2023-31248 which was promised in v1.

Martin Doucha (5):
  tst_rtnetlink: Refactor helper function for generic use
  tst_netlink_destroy_context(): Allow safely passing NULL context
  crypto: Replace old netlink helper functions with netlink contexts
  tst_netlink: Add helper functions for handling generic attributes
  Add test for CVE 2023-31248

 doc/C-Test-Network-API.asciidoc         | 159 +++++++++---------
 include/tst_crypto.h                    |  69 +-------
 include/tst_netdevice.h                 |   8 +-
 include/tst_netlink.h                   | 195 +++++++++++++---------
 include/tst_rtnetlink.h                 | 108 ------------
 lib/tst_crypto.c                        |  90 ++--------
 lib/tst_netdevice.c                     | 115 ++++++-------
 lib/{tst_rtnetlink.c => tst_netlink.c}  | 170 ++++++++++++++-----
 testcases/cve/tcindex01.c               |  16 +-
 testcases/kernel/crypto/crypto_user01.c |  58 +++----
 testcases/kernel/crypto/crypto_user02.c |  17 +-
 testcases/kernel/crypto/pcrypt_aead01.c |  10 +-
 testcases/network/iptables/Makefile     |   2 +-
 testcases/network/iptables/nft02.c      | 211 ++++++++++++++++++++++++
 14 files changed, 667 insertions(+), 561 deletions(-)
 delete mode 100644 include/tst_rtnetlink.h
 rename lib/{tst_rtnetlink.c => tst_netlink.c} (63%)
 create mode 100644 testcases/network/iptables/nft02.c

-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use
  2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
@ 2023-11-14 12:31 ` Martin Doucha
  2023-11-14 19:14   ` Petr Vorel
  2023-11-14 12:31 ` [LTP] [PATCH v2 2/5] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

The netlink context structure can be used for any netlink protocol,
not just for NETLINK_ROUTE. Change the RTNL prefix to NETLINK on
all helper functions which don't use NETLINK_ROUTE features and
add a new protocol parameter to tst_netlink_create_context().

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---

Changes since v1: Rebased

 doc/C-Test-Network-API.asciidoc | 155 ++++++++++++++++----------------
 include/tst_rtnetlink.h         |  85 +++++++++---------
 lib/tst_netdevice.c             |  93 +++++++++----------
 lib/tst_rtnetlink.c             |  83 ++++++++---------
 testcases/cve/tcindex01.c       |   2 +-
 5 files changed, 212 insertions(+), 206 deletions(-)

diff --git a/doc/C-Test-Network-API.asciidoc b/doc/C-Test-Network-API.asciidoc
index 3bf2a1f8a..25e4bbd18 100644
--- a/doc/C-Test-Network-API.asciidoc
+++ b/doc/C-Test-Network-API.asciidoc
@@ -143,7 +143,7 @@ static void setup(void)
 When opening a localhost socket isn't enough and the test needs special device
 or routing configuration, the netdevice library can create the required network
 setup without calling external programs. Internally, the netdevice functions
-use a rtnetlink socket to communicate with the kernel.
+use a netlink socket to communicate with the kernel.
 
 All of these functions will call +tst_brk()+ on failure, unless stated
 otherwise. Error values described below are returned only during test cleanup
@@ -274,12 +274,12 @@ static void setup(void)
 }
 -------------------------------------------------------------------------------
 
-3 rtnetlink API
+3 Netlink API
 ---------------
 
 +#include "tst_rtnetlink.h"+
 
-The rtnetlink library provides helper functions for constructing and sending
+The netlink library provides helper functions for constructing and sending
 arbitrary messages and parsing kernel responses.
 
 All of the functions below will call +tst_brk()+ on failure, unless stated
@@ -291,7 +291,7 @@ stage.
 
 [source,c]
 -------------------------------------------------------------------------------
-struct tst_rtnl_context;
+struct tst_netlink_context;
 
 struct tst_rtnl_attr_list {
 	unsigned short type;
@@ -300,7 +300,7 @@ struct tst_rtnl_attr_list {
 	const struct tst_rtnl_attr_list *sublist;
 };
 
-struct tst_rtnl_message {
+struct tst_netlink_message {
 	struct nlmsghdr *header;
 	struct nlmsgerr *err;
 	void *payload;
@@ -308,10 +308,10 @@ struct tst_rtnl_message {
 };
 -------------------------------------------------------------------------------
 
-+struct tst_rtnl_context+ is an opaque rtnetlink socket with buffer for
++struct tst_netlink_context+ is an opaque netlink socket with buffer for
 constructing and sending arbitrary messages using the functions described
-below. Create a new context using +RTNL_CREATE_CONTEXT()+, then free it using
-+RTNL_DESTROY_CONTEXT()+ when you're done with it.
+below. Create a new context using +NETLINK_CREATE_CONTEXT()+, then free it
+using +NETLINK_DESTROY_CONTEXT()+ when you're done with it.
 
 +struct tst_rtnl_attr_list+ is a helper structure for defining complex
 rtnetlink message attribute payloads, including nested attribute lists. Every
@@ -331,10 +331,10 @@ negative +len+.
   to the +len+ field. If you do not want to add nested attributes, set
   +sublist+ to +NULL+.
 
-+struct tst_rtnl_message+ is a structure holding partially parsed rtnetlink
-messages received from the kernel. +RTNL_RECV()+ returns an array of these
++struct tst_netlink_message+ is a structure holding partially parsed netlink
+messages received from the kernel. +NETLINK_RECV()+ returns an array of these
 structures with the last item having +NULL+ in the +header+ field. Call
-+RTNL_FREE_MESSAGE()+ to free a message list returned by +RTNL_RECV()+.
++NETLINK_FREE_MESSAGE()+ to free a message list returned by +NETLINK_RECV()+.
 
 - +header+ is the netlink header structure of the message. +NULL+ in the header
   field terminates a list of messages.
@@ -349,83 +349,86 @@ structures with the last item having +NULL+ in the +header+ field. Call
 3.2 Sending and receiving messages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- +struct tst_rtnl_context *RTNL_CREATE_CONTEXT(void)+ – Creates a new
-  rtnetlink communication context for use with the functions described below.
-  Returns +NULL+ on error.
+- +struct tst_netlink_context *NETLINK_CREATE_CONTEXT(int protocol)+ – Creates
+  a new netlink communication context with given netlink protocol for use
+  with the functions described below. Returns +NULL+ on error.
 
-- +void RTNL_FREE_MESSAGE(struct tst_rtnl_message *msg)+ – Frees an array of
-  messages returned by +RTNL_RECV()+.
+- +void NETLINK_FREE_MESSAGE(struct tst_netlink_message *msg)+ – Frees
+  an array of messages returned by +NETLINK_RECV()+.
 
-- +void RTNL_DESTROY_CONTEXT(struct tst_rtnl_context *ctx)+ – Closes a
-  communication context created by +RTNL_CREATE_CONTEXT()+.
+- +void NETLINK_DESTROY_CONTEXT(struct tst_netlink_context *ctx)+ – Closes a
+  communication context created by +NETLINK_CREATE_CONTEXT()+.
 
-- +int RTNL_SEND(struct tst_rtnl_context *ctx)+ – Sends all messages waiting
-  in +ctx+ buffer to the kernel. If there are multiple messages to send, a new
-  +NLMSG_DONE+ message will be added automatically. Returns the number of
-  bytes sent on success. Return 0 or negative value on error.
+- +int NETLINK_SEND(struct tst_netlink_context *ctx)+ – Sends all messages
+  waiting in +ctx+ buffer to the kernel. If there are multiple messages
+  to send, a new +NLMSG_DONE+ message will be added automatically. Returns
+  the number of bytes sent on success. Return 0 or negative value on error.
 
-- +int RTNL_SEND_VALIDATE(struct tst_rtnl_context *ctx)+ – Sends all messages
-  just like +RTNL_SEND()+, then receives the response from the kernel and
-  validates results of requests sent with the +NLM_F_ACK+ flag. This function
-  calls +tst_brk()+ as usual if communication fails but it will return error
-  status without terminating the test if one of the received messages contains
-  error code. See +RTNL_CHECK_ACKS()+ below for explanation of the return
-  value.
+- +int NETLINK_SEND_VALIDATE(struct tst_netlink_context *ctx)+ – Sends all
+  messages just like +NETLINK_SEND()+, then receives the response from
+  the kernel and validates results of requests sent with the +NLM_F_ACK+ flag.
+  This function calls +tst_brk()+ as usual if communication fails but it will
+  return error status without terminating the test if one of the received
+  messages contains error code. See +NETLINK_CHECK_ACKS()+ below for
+  explanation of the return value.
 
-- +int RTNL_WAIT(struct tst_rtnl_context *ctx)+ – Waits until data becomes
-  available to read from the rtnetlink socket (timeout: 1 second). Returns 1
+- +int NETLINK_WAIT(struct tst_netlink_context *ctx)+ – Waits until data becomes
+  available to read from the netlink socket (timeout: 1 second). Returns 1
   if there is data to read, 0 on timeout or -1 on error.
 
-- +struct tst_rtnl_message *RTNL_RECV(struct tst_rtnl_context *ctx)+ – Receives
-  rtnetlink messages from the kernel. The messages are received in non-blocking
-  mode so calling +RTNL_WAIT()+ first is recommended. Returns an array of
-  partially parsed messages terminated by an item with +NULL+ in the +header+
-  field. On error or when there are no messages to receive, returns +NULL+.
-  Call +RTNL_FREE_MESSAGE()+ to free the returned data.
-
-- +int RTNL_CHECK_ACKS(struct tst_rtnl_context *ctx, struct tst_rtnl_message
-  *response)+ – Validate results of requests sent with the +NLM_F_ACK+ flag.
-  Do not call +RTNL_ADD_MESSAGE()+ between +RTNL_SEND()+ and
-  +RTNL_CHECK_ACKS()+ because it will reset the state of +ctx+ and prevent
-  result validation. Returns 1 if all messages sent with the +NLM_F_ACK+ flag
-  have a corresponding message in +response+ and the error code is 0. If any
-  of the expected response messages is missing, this function will call
-  +tst_brk()+ (or return 0 during test cleanup phase). If any of the response
-  messages has non-zero error code, this function will return 0 and store the
-  first non-zero error code in global variable +tst_rtnl_errno+ (sign-flipped
-  just like regular libc +errno+).
+- +struct tst_netlink_message *NETLINK_RECV(struct tst_netlink_context *ctx)+ –
+  Receives netlink messages from the kernel. The messages are received
+  in non-blocking mode so calling +NETLINK_WAIT()+ first is recommended.
+  Returns an array of partially parsed messages terminated by an item with
+  +NULL+ in the +header+ field. On error or when there are no messages
+  to receive, returns +NULL+. Call +NETLINK_FREE_MESSAGE()+ to free
+  the returned data.
+
+- +int NETLINK_CHECK_ACKS(struct tst_netlink_context *ctx,
+  struct tst_netlink_message *response)+ – Validate results of requests sent
+  with the +NLM_F_ACK+ flag. Do not call +NETLINK_ADD_MESSAGE()+ between
+  +NETLINK_SEND()+ and +NETLINK_CHECK_ACKS()+ because it will reset the state
+  of +ctx+ and prevent result validation. Returns 1 if all messages sent
+  with the +NLM_F_ACK+ flag have a corresponding message in +response+ and
+  the error code is 0. If any of the expected response messages is missing,
+  this function will call +tst_brk()+ (or return 0 during test cleanup phase).
+  If any of the response messages has non-zero error code, this function will
+  return 0 and store the first non-zero error code in global variable
+  +tst_netlink_errno+ (sign-flipped just like regular libc +errno+).
 
 3.3 Creating messages
 ~~~~~~~~~~~~~~~~~~~~~
 
-- +int RTNL_ADD_MESSAGE(struct tst_rtnl_context *ctx, const struct nlmsghdr
-  *header, const void *payload, size_t payload_size)+ – Adds new rtnetlink
-  message to +ctx+ buffer. You need to provide message +header+ and optional
-  +payload+. +payload_size+ is the size of +payload+ data in bytes. If you
-  don't want to add any payload data, set +payload+ to +NULL+ and
+- +int NETLINK_ADD_MESSAGE(struct tst_netlink_context *ctx, const struct
+  nlmsghdr *header, const void *payload, size_t payload_size)+ – Adds new
+  netlink message to +ctx+ buffer. You need to provide message +header+ and
+  optional +payload+. +payload_size+ is the size of +payload+ data in bytes.
+  If you don't want to add any payload data, set +payload+ to +NULL+ and
   +payload_size+ to 0. This function will automatically fill the +nlmsg_len+,
   +nlmsg_seq+ and +nlmsg_pid+ fields of the new message header. You don't need
   to set those. It'll also automatically add +NLM_F_MULTI+ flag when needed.
   Returns 1 on success, 0 on error. Note that the first call of
-  +RTNL_ADD_MESSAGE()+ after +RTNL_SEND()+ will reset the state of +ctx+
-  and +RTNL_CHECK_ACKS()+ will not work correctly until the next +RTNL_SEND()+.
-
-- +int RTNL_ADD_ATTR(struct tst_rtnl_context *ctx, unsigned short type, const
-  void *data, unsigned short len)+ – Adds new attribute to the last message
-  in +ctx+ buffer. See +RTNL_ADD_MESSAGE()+. You need to provide attribute
-  +type+ which will be stored in +struct rtattr.rta_type+, optional payload
-  +data+ and payload size +len+ in bytes. If you don't want to add any payload,
-  set +data+ to +NULL+ and +len+ to 0. Returns 1 on success, 0 on error.
-
-- +int RTNL_ADD_ATTR_STRING(struct tst_rtnl_context *ctx, unsigned short type,
-  const char *data)+ – Adds new string attribute to the last message in +ctx+
-  buffer. Parameters and return value are the same as for +RTNL_ADD_ATTR()+,
-  except the payload length is calculated using +strlen()+.
-
-- +int RTNL_ADD_ATTR_LIST(struct tst_rtnl_context *ctx, const struct
+  +NETLINK_ADD_MESSAGE()+ after +NETLINK_SEND()+ will reset the state of +ctx+
+  and +NETLINK_CHECK_ACKS()+ will not work correctly until the next
+  +NETLINK_SEND()+.
+
+- +int RTNL_ADD_ATTR(struct tst_netlink_context *ctx, unsigned short type,
+  const void *data, unsigned short len)+ – Adds new attribute to the last
+  message in +ctx+ buffer. See +NETLINK_ADD_MESSAGE()+. You need to provide
+  attribute +type+ which will be stored in +struct rtattr.rta_type+, optional
+  payload +data+ and payload size +len+ in bytes. If you don't want to add any
+  payload, set +data+ to +NULL+ and +len+ to 0. Returns 1 on success,
+  0 on error.
+
+- +int RTNL_ADD_ATTR_STRING(struct tst_netlink_context *ctx, unsigned short
+  type, const char *data)+ – Adds new string attribute to the last message
+  in +ctx+ buffer. Parameters and return value are the same as for
+  +RTNL_ADD_ATTR()+, except the payload length is calculated using +strlen()+.
+
+- +int RTNL_ADD_ATTR_LIST(struct tst_netlink_context *ctx, const struct
   tst_rtnl_attr_list *list)+ – Adds a list of attributes to the last message
   in +ctx+ buffer. See description of +struct tst_rtnl_attr_list+ and
-  +RTNL_ADD_MESSAGE()+ above.  Returns the number of added attributes on
+  +NETLINK_ADD_MESSAGE()+ above.  Returns the number of added attributes on
   success (nested attributes are not counted), -1 on error.
 
 Example Usage
@@ -447,7 +450,7 @@ Example Usage
 
 void setup(void)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int index, ret;
 	in_addr_t addr;
 
@@ -465,12 +468,12 @@ void setup(void)
 	index = NETDEV_INDEX_BY_NAME("ltp_veth1");
 	info.ifa_index = index;
 
-	ctx = RTNL_CREATE_CONTEXT();
-	RTNL_ADD_MESSAGE(ctx, &header, &info, sizeof(info));
+	ctx = NETLINK_CREATE_CONTEXT(NETLINK_ROUTE);
+	NETLINK_ADD_MESSAGE(ctx, &header, &info, sizeof(info));
 	addr = inet_addr("192.168.123.45");
 	RTNL_ADD_ATTR(ctx, IFA_LOCAL, &addr, sizeof(addr));
-	ret = RTNL_SEND_VALIDATE(ctx);
-	RTNL_DESTROY_CONTEXT(ctx);
+	ret = NETLINK_SEND_VALIDATE(ctx);
+	NETLINK_DESTROY_CONTEXT(ctx);
 
 	if (!ret) {
 		tst_brk(TBROK, "Failed to set ltp_veth1 address");
diff --git a/include/tst_rtnetlink.h b/include/tst_rtnetlink.h
index 6a0c53df4..c5f295a38 100644
--- a/include/tst_rtnetlink.h
+++ b/include/tst_rtnetlink.h
@@ -5,7 +5,7 @@
 #ifndef TST_RTNETLINK_H
 #define TST_RTNETLINK_H
 
-struct tst_rtnl_context;
+struct tst_netlink_context;
 
 struct tst_rtnl_attr_list {
 	unsigned short type;
@@ -14,71 +14,72 @@ struct tst_rtnl_attr_list {
 	const struct tst_rtnl_attr_list *sublist;
 };
 
-struct tst_rtnl_message {
+struct tst_netlink_message {
 	struct nlmsghdr *header;
 	struct nlmsgerr *err;
 	void *payload;
 	size_t payload_size;
 };
 
-extern int tst_rtnl_errno;
+extern int tst_netlink_errno;
 
 /* Open a netlink socket */
-struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
-	const int lineno);
-#define RTNL_CREATE_CONTEXT() tst_rtnl_create_context(__FILE__, __LINE__)
+struct tst_netlink_context *tst_netlink_create_context(const char *file,
+	const int lineno, int protocol);
+#define NETLINK_CREATE_CONTEXT(protocol) \
+	tst_netlink_create_context(__FILE__, __LINE__, (protocol))
 
-/* Free a tst_rtnl_message array returned by tst_rtnl_recv() */
-void tst_rtnl_free_message(struct tst_rtnl_message *msg);
-#define RTNL_FREE_MESSAGE tst_rtnl_free_message
+/* Free a tst_netlink_message array returned by tst_netlink_recv() */
+void tst_netlink_free_message(struct tst_netlink_message *msg);
+#define NETLINK_FREE_MESSAGE tst_netlink_free_message
 
 /* Close netlink socket */
-void tst_rtnl_destroy_context(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx);
-#define RTNL_DESTROY_CONTEXT(ctx) \
-	tst_rtnl_destroy_context(__FILE__, __LINE__, (ctx))
+void tst_netlink_destroy_context(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_DESTROY_CONTEXT(ctx) \
+	tst_netlink_destroy_context(__FILE__, __LINE__, (ctx))
 
 /* Send all messages in given buffer */
-int tst_rtnl_send(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx);
-#define RTNL_SEND(ctx) tst_rtnl_send(__FILE__, __LINE__, (ctx))
+int tst_netlink_send(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx))
 
 /* Send all messages in given buffer and validate kernel response */
-int tst_rtnl_send_validate(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx);
-#define RTNL_SEND_VALIDATE(ctx) \
-	tst_rtnl_send_validate(__FILE__, __LINE__, (ctx))
+int tst_netlink_send_validate(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_SEND_VALIDATE(ctx) \
+	tst_netlink_send_validate(__FILE__, __LINE__, (ctx))
 
 /* Wait until data is available for reading from the netlink socket */
-int tst_rtnl_wait(struct tst_rtnl_context *ctx);
-#define RTNL_WAIT tst_rtnl_wait
+int tst_netlink_wait(struct tst_netlink_context *ctx);
+#define NETLINK_WAIT tst_netlink_wait
 
 /*
  * Read from netlink socket and return an array of partially parsed messages.
  * header == NULL indicates end of array.
  */
-struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx);
-#define RTNL_RECV(ctx) tst_rtnl_recv(__FILE__, __LINE__, (ctx))
+struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx))
 
 /* Add new message to buffer */
-int tst_rtnl_add_message(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, const struct nlmsghdr *header,
+int tst_netlink_add_message(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, const struct nlmsghdr *header,
 	const void *payload, size_t payload_size);
-#define RTNL_ADD_MESSAGE(ctx, header, payload, psize) \
-	tst_rtnl_add_message(__FILE__, __LINE__, (ctx), (header), (payload), \
-		(psize))
+#define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \
+	tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \
+		(payload), (psize))
 
 /* Add arbitrary attribute to last message */
 int tst_rtnl_add_attr(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, unsigned short type, const void *data,
+	struct tst_netlink_context *ctx, unsigned short type, const void *data,
 	unsigned short len);
 #define RTNL_ADD_ATTR(ctx, type, data, len) \
 	tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
 
 /* Add string attribute to last message */
 int tst_rtnl_add_attr_string(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, unsigned short type, const char *data);
+	struct tst_netlink_context *ctx, unsigned short type, const char *data);
 #define RTNL_ADD_ATTR_STRING(ctx, type, data) \
 	tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
 
@@ -87,22 +88,22 @@ int tst_rtnl_add_attr_string(const char *file, const int lineno,
  * by attribute with negative length. Nested sublists are supported.
  */
 int tst_rtnl_add_attr_list(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, const struct tst_rtnl_attr_list *list);
+	struct tst_netlink_context *ctx, const struct tst_rtnl_attr_list *list);
 #define RTNL_ADD_ATTR_LIST(ctx, list) \
 	tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list))
 
 /* Check that all sent messages with NLM_F_ACK flag have been acked without
  * error. Usage:
  *
- * tst_rtnl_send(ctx);
- * tst_rtnl_wait(ctx);
- * response = tst_rtnl_recv(ctx);
- * if (!tst_rtnl_check_acks(ctx, response)) { ... }
- * tst_rtnl_free_message(response);
+ * tst_netlink_send(ctx);
+ * tst_netlink_wait(ctx);
+ * response = tst_netlink_recv(ctx);
+ * if (!tst_netlink_check_acks(ctx, response)) { ... }
+ * tst_netlink_free_message(response);
  */
-int tst_rtnl_check_acks(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, struct tst_rtnl_message *response);
-#define RTNL_CHECK_ACKS(ctx, response) \
-	tst_rtnl_context(__FILE__, __LINE__, (ctx), (response))
+int tst_netlink_check_acks(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, struct tst_netlink_message *response);
+#define NETLINK_CHECK_ACKS(ctx, response) \
+	tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response))
 
 #endif /* TST_RTNETLINK_H */
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index dba44c623..5873b3d58 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -15,23 +15,24 @@
 #include "tst_rtnetlink.h"
 #include "tst_netdevice.h"
 
-static struct tst_rtnl_context *create_request(const char *file,
+static struct tst_netlink_context *create_request(const char *file,
 	const int lineno, unsigned int type, unsigned int flags,
 	const void *payload, size_t psize)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	struct nlmsghdr header = {
 		.nlmsg_type = type,
 		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags,
 	};
 
-	ctx = tst_rtnl_create_context(file, lineno);
+	ctx = tst_netlink_create_context(file, lineno, NETLINK_ROUTE);
 
 	if (!ctx)
 		return NULL;
 
-	if (!tst_rtnl_add_message(file, lineno, ctx, &header, payload, psize)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+	if (!tst_netlink_add_message(file, lineno, ctx, &header, payload,
+		psize)) {
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return NULL;
 	}
 
@@ -103,7 +104,7 @@ int tst_create_veth_pair(const char *file, const int lineno, int strict,
 {
 	int ret;
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	struct tst_rtnl_attr_list peerinfo[] = {
 		{IFLA_IFNAME, ifname2, strlen(ifname2) + 1, NULL},
 		{0, NULL, -1, NULL}
@@ -141,17 +142,17 @@ int tst_create_veth_pair(const char *file, const int lineno, int strict,
 		return 0;
 
 	if (tst_rtnl_add_attr_list(file, lineno, ctx, attrs) != 2) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to create veth interfaces %s+%s: %s", ifname1,
-			ifname2, tst_strerrno(tst_rtnl_errno));
+			ifname2, tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -162,7 +163,7 @@ int tst_netdev_add_device(const char *file, const int lineno, int strict,
 {
 	int ret;
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	struct tst_rtnl_attr_list attrs[] = {
 		{IFLA_IFNAME, ifname, strlen(ifname) + 1, NULL},
 		{IFLA_LINKINFO, NULL, 0, (const struct tst_rtnl_attr_list[]){
@@ -185,17 +186,17 @@ int tst_netdev_add_device(const char *file, const int lineno, int strict,
 		return 0;
 
 	if (tst_rtnl_add_attr_list(file, lineno, ctx, attrs) != 2) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to create %s device %s: %s", devtype, ifname,
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -205,7 +206,7 @@ int tst_netdev_remove_device(const char *file, const int lineno, int strict,
 	const char *ifname)
 {
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int ret;
 
 	if (strlen(ifname) >= IFNAMSIZ) {
@@ -220,17 +221,17 @@ int tst_netdev_remove_device(const char *file, const int lineno, int strict,
 		return 0;
 
 	if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to remove netdevice %s: %s", ifname,
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -241,7 +242,7 @@ static int modify_address(const char *file, const int lineno, int strict,
 	unsigned int family, const void *address, unsigned int prefix,
 	size_t addrlen, uint32_t addr_flags)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int index, ret;
 	struct ifaddrmsg info = {
 		.ifa_family = family,
@@ -264,23 +265,23 @@ static int modify_address(const char *file, const int lineno, int strict,
 
 	if (!tst_rtnl_add_attr(file, lineno, ctx, IFA_FLAGS, &addr_flags,
 		sizeof(uint32_t))) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (!tst_rtnl_add_attr(file, lineno, ctx, IFA_LOCAL, address,
 		addrlen)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to modify %s network address: %s", ifname,
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -322,7 +323,7 @@ static int change_ns(const char *file, const int lineno, int strict,
 	const char *ifname, unsigned short attr, uint32_t value)
 {
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int ret;
 
 	if (strlen(ifname) >= IFNAMSIZ) {
@@ -337,23 +338,23 @@ static int change_ns(const char *file, const int lineno, int strict,
 		return 0;
 
 	if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (!tst_rtnl_add_attr(file, lineno, ctx, attr, &value,
 		sizeof(uint32_t))) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to move %s to another namespace: %s", ifname,
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -377,7 +378,7 @@ static int modify_route(const char *file, const int lineno, int strict,
 	size_t srclen, const void *dstaddr, unsigned int dstprefix,
 	size_t dstlen, const void *gateway, size_t gatewaylen)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int ret;
 	int32_t index;
 	struct rtmsg info = {
@@ -420,35 +421,35 @@ static int modify_route(const char *file, const int lineno, int strict,
 
 	if (srcaddr && !tst_rtnl_add_attr(file, lineno, ctx, RTA_SRC, srcaddr,
 		srclen)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (dstaddr && !tst_rtnl_add_attr(file, lineno, ctx, RTA_DST, dstaddr,
 		dstlen)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (gateway && !tst_rtnl_add_attr(file, lineno, ctx, RTA_GATEWAY,
 		gateway, gatewaylen)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (ifname && !tst_rtnl_add_attr(file, lineno, ctx, RTA_OIF, &index,
 		sizeof(index))) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to modify network route: %s",
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
@@ -528,7 +529,7 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
 	unsigned int handle, unsigned int info, const char *qd_kind,
 	const struct tst_rtnl_attr_list *config)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	int ret;
 	struct tcmsg msg = {
 		.tcm_family = family,
@@ -560,22 +561,22 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
 		return 0;
 
 	if (!tst_rtnl_add_attr_string(file, lineno, ctx, TCA_KIND, qd_kind)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
 	if (config && !tst_rtnl_add_attr_list(file, lineno, ctx, config)) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return 0;
 	}
 
-	ret = tst_rtnl_send_validate(file, lineno, ctx);
-	tst_rtnl_destroy_context(file, lineno, ctx);
+	ret = tst_netlink_send_validate(file, lineno, ctx);
+	tst_netlink_destroy_context(file, lineno, ctx);
 
 	if (strict && !ret) {
 		tst_brk_(file, lineno, TBROK,
 			"Failed to modify %s: %s", object,
-			tst_strerrno(tst_rtnl_errno));
+			tst_strerrno(tst_netlink_errno));
 	}
 
 	return ret;
diff --git a/lib/tst_rtnetlink.c b/lib/tst_rtnetlink.c
index a2411dfde..eacfdced1 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_rtnetlink.c
@@ -15,7 +15,7 @@
 #include "tst_test.h"
 #include "tst_rtnetlink.h"
 
-struct tst_rtnl_context {
+struct tst_netlink_context {
 	int socket;
 	pid_t pid;
 	uint32_t seq;
@@ -24,10 +24,10 @@ struct tst_rtnl_context {
 	struct nlmsghdr *curmsg;
 };
 
-int tst_rtnl_errno;
+int tst_netlink_errno;
 
-static int tst_rtnl_grow_buffer(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, size_t size)
+static int netlink_grow_buffer(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, size_t size)
 {
 	size_t needed, offset, curlen = NLMSG_ALIGN(ctx->datalen);
 	char *buf;
@@ -52,21 +52,22 @@ static int tst_rtnl_grow_buffer(const char *file, const int lineno,
 	return 1;
 }
 
-void tst_rtnl_destroy_context(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx)
+void tst_netlink_destroy_context(const char *file, const int lineno,
+	struct tst_netlink_context *ctx)
 {
 	safe_close(file, lineno, NULL, ctx->socket);
 	free(ctx->buffer);
 	free(ctx);
 }
 
-struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
-	const int lineno)
+struct tst_netlink_context *tst_netlink_create_context(const char *file,
+	const int lineno, int protocol)
 {
-	struct tst_rtnl_context *ctx;
+	struct tst_netlink_context *ctx;
 	struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
 
-	ctx = safe_malloc(file, lineno, NULL, sizeof(struct tst_rtnl_context));
+	ctx = safe_malloc(file, lineno, NULL,
+		sizeof(struct tst_netlink_context));
 
 	if (!ctx)
 		return NULL;
@@ -78,7 +79,7 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
 	ctx->datalen = 0;
 	ctx->curmsg = NULL;
 	ctx->socket = safe_socket(file, lineno, NULL, AF_NETLINK,
-		SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+		SOCK_DGRAM | SOCK_CLOEXEC, protocol);
 
 	if (ctx->socket < 0) {
 		free(ctx);
@@ -87,14 +88,14 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
 
 	if (safe_bind(file, lineno, NULL, ctx->socket, (struct sockaddr *)&addr,
 		sizeof(addr))) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return NULL;
 	}
 
 	ctx->buffer = safe_malloc(file, lineno, NULL, ctx->bufsize);
 
 	if (!ctx->buffer) {
-		tst_rtnl_destroy_context(file, lineno, ctx);
+		tst_netlink_destroy_context(file, lineno, ctx);
 		return NULL;
 	}
 
@@ -103,7 +104,7 @@ struct tst_rtnl_context *tst_rtnl_create_context(const char *file,
 	return ctx;
 }
 
-void tst_rtnl_free_message(struct tst_rtnl_message *msg)
+void tst_netlink_free_message(struct tst_netlink_message *msg)
 {
 	if (!msg)
 		return;
@@ -114,8 +115,8 @@ void tst_rtnl_free_message(struct tst_rtnl_message *msg)
 	free(msg);
 }
 
-int tst_rtnl_send(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx)
+int tst_netlink_send(const char *file, const int lineno,
+	struct tst_netlink_context *ctx)
 {
 	int ret;
 	struct sockaddr_nl addr = { .nl_family = AF_NETLINK };
@@ -136,7 +137,7 @@ int tst_rtnl_send(const char *file, const int lineno,
 	if (ctx->curmsg->nlmsg_flags & NLM_F_MULTI) {
 		struct nlmsghdr eom = { .nlmsg_type = NLMSG_DONE };
 
-		if (!tst_rtnl_add_message(file, lineno, ctx, &eom, NULL, 0))
+		if (!tst_netlink_add_message(file, lineno, ctx, &eom, NULL, 0))
 			return 0;
 
 		/* NLMSG_DONE message must not have NLM_F_MULTI flag */
@@ -153,7 +154,7 @@ int tst_rtnl_send(const char *file, const int lineno,
 	return ret;
 }
 
-int tst_rtnl_wait(struct tst_rtnl_context *ctx)
+int tst_netlink_wait(struct tst_netlink_context *ctx)
 {
 	struct pollfd fdinfo = {
 		.fd = ctx->socket,
@@ -163,11 +164,11 @@ int tst_rtnl_wait(struct tst_rtnl_context *ctx)
 	return poll(&fdinfo, 1, 1000);
 }
 
-struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx)
+struct tst_netlink_message *tst_netlink_recv(const char *file,
+	const int lineno, struct tst_netlink_context *ctx)
 {
 	char tmp, *tmpbuf, *buffer = NULL;
-	struct tst_rtnl_message *ret;
+	struct tst_netlink_message *ret;
 	struct nlmsghdr *ptr;
 	size_t retsize, bufsize = 0;
 	ssize_t size;
@@ -215,7 +216,7 @@ struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
 	for (; size_left > 0 && NLMSG_OK(ptr, size_left); msgcount++)
 		ptr = NLMSG_NEXT(ptr, size_left);
 
-	retsize = (msgcount + 1) * sizeof(struct tst_rtnl_message);
+	retsize = (msgcount + 1) * sizeof(struct tst_netlink_message);
 	ret = safe_malloc(file, lineno, NULL, retsize);
 
 	if (!ret) {
@@ -239,14 +240,14 @@ struct tst_rtnl_message *tst_rtnl_recv(const char *file, const int lineno,
 	return ret;
 }
 
-int tst_rtnl_add_message(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, const struct nlmsghdr *header,
+int tst_netlink_add_message(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, const struct nlmsghdr *header,
 	const void *payload, size_t payload_size)
 {
 	size_t size;
 	unsigned int extra_flags = 0;
 
-	if (!tst_rtnl_grow_buffer(file, lineno, ctx, NLMSG_SPACE(payload_size)))
+	if (!netlink_grow_buffer(file, lineno, ctx, NLMSG_SPACE(payload_size)))
 		return 0;
 
 	if (!ctx->curmsg) {
@@ -280,7 +281,7 @@ int tst_rtnl_add_message(const char *file, const int lineno,
 }
 
 int tst_rtnl_add_attr(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, unsigned short type,
+	struct tst_netlink_context *ctx, unsigned short type,
 	const void *data, unsigned short len)
 {
 	size_t size;
@@ -292,7 +293,7 @@ int tst_rtnl_add_attr(const char *file, const int lineno,
 		return 0;
 	}
 
-	if (!tst_rtnl_grow_buffer(file, lineno, ctx, RTA_SPACE(len)))
+	if (!netlink_grow_buffer(file, lineno, ctx, RTA_SPACE(len)))
 		return 0;
 
 	size = NLMSG_ALIGN(ctx->curmsg->nlmsg_len);
@@ -307,7 +308,7 @@ int tst_rtnl_add_attr(const char *file, const int lineno,
 }
 
 int tst_rtnl_add_attr_string(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, unsigned short type,
+	struct tst_netlink_context *ctx, unsigned short type,
 	const char *data)
 {
 	return tst_rtnl_add_attr(file, lineno, ctx, type, data,
@@ -315,7 +316,7 @@ int tst_rtnl_add_attr_string(const char *file, const int lineno,
 }
 
 int tst_rtnl_add_attr_list(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx,
+	struct tst_netlink_context *ctx,
 	const struct tst_rtnl_attr_list *list)
 {
 	int i, ret;
@@ -359,8 +360,8 @@ int tst_rtnl_add_attr_list(const char *file, const int lineno,
 	return i;
 }
 
-int tst_rtnl_check_acks(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx, struct tst_rtnl_message *res)
+int tst_netlink_check_acks(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, struct tst_netlink_message *res)
 {
 	struct nlmsghdr *msg = (struct nlmsghdr *)ctx->buffer;
 	int size_left = ctx->datalen;
@@ -382,7 +383,7 @@ int tst_rtnl_check_acks(const char *file, const int lineno,
 		}
 
 		if (res->err->error) {
-			tst_rtnl_errno = -res->err->error;
+			tst_netlink_errno = -res->err->error;
 			return 0;
 		}
 	}
@@ -390,25 +391,25 @@ int tst_rtnl_check_acks(const char *file, const int lineno,
 	return 1;
 }
 
-int tst_rtnl_send_validate(const char *file, const int lineno,
-	struct tst_rtnl_context *ctx)
+int tst_netlink_send_validate(const char *file, const int lineno,
+	struct tst_netlink_context *ctx)
 {
-	struct tst_rtnl_message *response;
+	struct tst_netlink_message *response;
 	int ret;
 
-	tst_rtnl_errno = 0;
+	tst_netlink_errno = 0;
 
-	if (tst_rtnl_send(file, lineno, ctx) <= 0)
+	if (tst_netlink_send(file, lineno, ctx) <= 0)
 		return 0;
 
-	tst_rtnl_wait(ctx);
-	response = tst_rtnl_recv(file, lineno, ctx);
+	tst_netlink_wait(ctx);
+	response = tst_netlink_recv(file, lineno, ctx);
 
 	if (!response)
 		return 0;
 
-	ret = tst_rtnl_check_acks(file, lineno, ctx, response);
-	tst_rtnl_free_message(response);
+	ret = tst_netlink_check_acks(file, lineno, ctx, response);
+	tst_netlink_free_message(response);
 
 	return ret;
 }
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
index 001056820..0fd254a92 100644
--- a/testcases/cve/tcindex01.c
+++ b/testcases/cve/tcindex01.c
@@ -95,7 +95,7 @@ static void run(void)
 		1, "tcindex");
 	ret = tst_netdev_add_traffic_filter(__FILE__, __LINE__, 0, DEVNAME,
 		qd_handle, 10, ETH_P_IP, 1, "tcindex", f_config);
-	TST_ERR = tst_rtnl_errno;
+	TST_ERR = tst_netlink_errno;
 	NETDEV_REMOVE_QDISC(DEVNAME, AF_UNSPEC, TC_H_ROOT, qd_handle, "htb");
 
 	if (ret)
-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 2/5] tst_netlink_destroy_context(): Allow safely passing NULL context
  2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
@ 2023-11-14 12:31 ` Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 3/5] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---

Changes since v1: None

 lib/tst_rtnetlink.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/tst_rtnetlink.c b/lib/tst_rtnetlink.c
index eacfdced1..bf782ffb5 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_rtnetlink.c
@@ -55,6 +55,9 @@ static int netlink_grow_buffer(const char *file, const int lineno,
 void tst_netlink_destroy_context(const char *file, const int lineno,
 	struct tst_netlink_context *ctx)
 {
+	if (!ctx)
+		return;
+
 	safe_close(file, lineno, NULL, ctx->socket);
 	free(ctx->buffer);
 	free(ctx);
-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 3/5] crypto: Replace old netlink helper functions with netlink contexts
  2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 2/5] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
@ 2023-11-14 12:31 ` Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 4/5] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248 Martin Doucha
  4 siblings, 0 replies; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

Finish refactoring of netlink helper functions for generic use
and replace the very limited netlink send/receive functions
used by the crypto tests with the new context-based helpers.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---

Changes since v1:
- Rebased
- Removed doc references to tst_crypto_session

The tst_netlink_context structure is initialized by NETLINK_CREATE_CONTEXT(),
no macro is needed or even desirable since it's an opaque structure. It has
no documentation so I've just removed the @relates references
to tst_crypto_session.

 doc/C-Test-Network-API.asciidoc         |   4 +-
 include/tst_crypto.h                    |  69 +---------
 include/tst_netdevice.h                 |   2 +-
 include/tst_netlink.h                   | 171 ++++++++++++++----------
 include/tst_rtnetlink.h                 | 109 ---------------
 lib/tst_crypto.c                        |  90 +++----------
 lib/tst_netdevice.c                     |   2 +-
 lib/{tst_rtnetlink.c => tst_netlink.c}  |   2 +-
 testcases/cve/tcindex01.c               |   2 +-
 testcases/kernel/crypto/crypto_user01.c |  58 +++-----
 testcases/kernel/crypto/crypto_user02.c |  17 +--
 testcases/kernel/crypto/pcrypt_aead01.c |  10 +-
 12 files changed, 159 insertions(+), 377 deletions(-)
 delete mode 100644 include/tst_rtnetlink.h
 rename lib/{tst_rtnetlink.c => tst_netlink.c} (99%)

diff --git a/doc/C-Test-Network-API.asciidoc b/doc/C-Test-Network-API.asciidoc
index 25e4bbd18..d04dd6aa3 100644
--- a/doc/C-Test-Network-API.asciidoc
+++ b/doc/C-Test-Network-API.asciidoc
@@ -277,7 +277,7 @@ static void setup(void)
 3 Netlink API
 ---------------
 
-+#include "tst_rtnetlink.h"+
++#include "tst_netlink.h"+
 
 The netlink library provides helper functions for constructing and sending
 arbitrary messages and parsing kernel responses.
@@ -443,7 +443,7 @@ Example Usage
 #include <arpa/inet.h>
 
 #include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
 #include "tst_netdevice.h"
 
 ...
diff --git a/include/tst_crypto.h b/include/tst_crypto.h
index ae406bd04..421e6b947 100644
--- a/include/tst_crypto.h
+++ b/include/tst_crypto.h
@@ -13,67 +13,12 @@
 #define TST_CRYPTO_H
 
 #include "lapi/cryptouser.h"
-
-/**
- * A reference to a crypto session and associated state.
- *
- * 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.
- *
- * Some functions, such as delete ALG, may return EBUSY in which case it is
- * safe to retry them. The retries field allows you to set the number of
- * times this should be done. If set to zero the operation will only be tried
- * once. For operations which do not return EBUSY, the field is ignored.
- *
- * Use TST_CRYPTO_SESSION_INIT to statically initialize this struct with sane
- * defaults.
- */
-struct tst_crypto_session {
-	/** File descriptor for the netlink socket */
-	int fd;
-	/** A sequence number used to identify responses from the kernel. */
-	uint32_t seq_num;
-	/** Number of times some operations will be retried. */
-	uint32_t retries;
-};
-
-/**
- * Default static definition of tst_crypto_session.
- *
- * @relates tst_crypto_session
- */
-#define TST_CRYPTO_SESSION_INIT {\
-	.fd = 0,                 \
-	.seq_num = 0,            \
-	.retries = 1000          \
-}
-
-/**
- * Creates a crypto session.
- *
- * @relates tst_crypto_session
- * @param ses Session structure to use, it can be uninitialized.
- *
- * 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);
-
-/**
- * Close a crypto session.
- *
- * @relates tst_crypto_session
- * @param ses The session to close.
- */
-void tst_crypto_close(struct tst_crypto_session *ses);
+#include "tst_netlink.h"
 
 /**
  * Add a crypto algorithm to a session.
  *
- * @relates tst_crypto_session
- * @param ses An open session.
+ * @param ctx Initialized netlink context
  * @param alg The crypto algorithm or module to add.
  *
  * This requests a new crypto algorithm/engine/module to be initialized by the
@@ -84,15 +29,15 @@ void tst_crypto_close(struct tst_crypto_session *ses);
  * @return On success it will return 0 otherwise it will return an inverted
  *         error code from the crypto layer.
  */
-int tst_crypto_add_alg(struct tst_crypto_session *ses,
+int tst_crypto_add_alg(struct tst_netlink_context *ctx,
 		       const struct crypto_user_alg *alg);
 
 /**
  * Delete a crypto algorithm from a session.
  *
- * @relates tst_crypto_session
- * @param ses An open session.
+ * @param ctx Initialized netlink context
  * @param alg The crypto algorithm to delete.
+ * @param retries Number of retries before giving up. Recommended value: 1000
  *
  * 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
@@ -106,7 +51,7 @@ int tst_crypto_add_alg(struct tst_crypto_session *ses,
  *         library, you don't need to log this error as it will already have
  *         been printed by tst_brk().
  */
-int tst_crypto_del_alg(struct tst_crypto_session *ses,
-		       const struct crypto_user_alg *alg);
+int tst_crypto_del_alg(struct tst_netlink_context *ctx,
+	const struct crypto_user_alg *alg, unsigned int retries);
 
 #endif	/* TST_CRYPTO_H */
diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h
index 5e62ba065..4239d0960 100644
--- a/include/tst_netdevice.h
+++ b/include/tst_netdevice.h
@@ -5,7 +5,7 @@
 #ifndef TST_NETDEVICE_H
 #define TST_NETDEVICE_H
 
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
 
 /* Find device index for given network interface name. */
 int tst_netdev_index_by_name(const char *file, const int lineno,
diff --git a/include/tst_netlink.h b/include/tst_netlink.h
index 2030ac30b..f10f1cf5d 100644
--- a/include/tst_netlink.h
+++ b/include/tst_netlink.h
@@ -1,11 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
- */
-
-/**
- * @file tst_netlink.h
- *
- * Library for communicating with the kernel over the netlink interface.
+ * Copyright (c) 2021 Linux Test Project
  */
 
 #ifndef TST_NETLINK_H
@@ -13,76 +7,105 @@
 
 #include <linux/netlink.h>
 
-#ifndef NETLINK_CRYPTO
-/**
- * The netlink-crypto socket protocol.
+struct tst_netlink_context;
+
+struct tst_rtnl_attr_list {
+	unsigned short type;
+	const void *data;
+	ssize_t len;
+	const struct tst_rtnl_attr_list *sublist;
+};
+
+struct tst_netlink_message {
+	struct nlmsghdr *header;
+	struct nlmsgerr *err;
+	void *payload;
+	size_t payload_size;
+};
+
+extern int tst_netlink_errno;
+
+/* Open a netlink socket */
+struct tst_netlink_context *tst_netlink_create_context(const char *file,
+	const int lineno, int protocol);
+#define NETLINK_CREATE_CONTEXT(protocol) \
+	tst_netlink_create_context(__FILE__, __LINE__, (protocol))
+
+/* Free a tst_netlink_message array returned by tst_netlink_recv() */
+void tst_netlink_free_message(struct tst_netlink_message *msg);
+#define NETLINK_FREE_MESSAGE tst_netlink_free_message
+
+/* Close netlink socket */
+void tst_netlink_destroy_context(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_DESTROY_CONTEXT(ctx) \
+	tst_netlink_destroy_context(__FILE__, __LINE__, (ctx))
+
+/* Send all messages in given buffer */
+int tst_netlink_send(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx))
+
+/* Send all messages in given buffer and validate kernel response */
+int tst_netlink_send_validate(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_SEND_VALIDATE(ctx) \
+	tst_netlink_send_validate(__FILE__, __LINE__, (ctx))
+
+/* Wait until data is available for reading from the netlink socket */
+int tst_netlink_wait(struct tst_netlink_context *ctx);
+#define NETLINK_WAIT tst_netlink_wait
+
+/*
+ * Read from netlink socket and return an array of partially parsed messages.
+ * header == NULL indicates end of array.
  */
-#define NETLINK_CRYPTO 21
-#endif
-
-/** @private */
-static inline ssize_t safe_netlink_send(const char *file, const int lineno,
-					int fd, const struct nlmsghdr *nh,
-					const void *payload)
-{
-	struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
-	struct iovec iov[2] = {
-		{(struct nlmsghdr *)nh, sizeof(*nh)},
-		{(void *)payload, nh->nlmsg_len - sizeof(*nh)}
-	};
-	struct msghdr msg = {
-		.msg_name = &sa,
-		.msg_namelen = sizeof(sa),
-		.msg_iov = iov,
-		.msg_iovlen = 2
-	};
-
-	return safe_sendmsg(file, lineno, nh->nlmsg_len, fd, &msg, 0);
-}
-
-/**
- * Sends a netlink message using safe_sendmsg().
- *
- * @param fd netlink socket file descriptor.
- * @param nl_header netlink header structure describing the message.
- * @param payload an opaque object containing the message data.
- *
- * You should set the message length, type and flags to appropriate values
- * within the nl_header object. See lib/tst_crypto.c for an example.
- *
- * @return The number of bytes sent.
+struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno,
+	struct tst_netlink_context *ctx);
+#define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx))
+
+/* Add new message to buffer */
+int tst_netlink_add_message(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, const struct nlmsghdr *header,
+	const void *payload, size_t payload_size);
+#define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \
+	tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \
+		(payload), (psize))
+
+/* Add arbitrary attribute to last message */
+int tst_rtnl_add_attr(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type, const void *data,
+	unsigned short len);
+#define RTNL_ADD_ATTR(ctx, type, data, len) \
+	tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
+
+/* Add string attribute to last message */
+int tst_rtnl_add_attr_string(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type, const char *data);
+#define RTNL_ADD_ATTR_STRING(ctx, type, data) \
+	tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
+
+/*
+ * Add list of arbitrary attributes to last message. The list is terminated
+ * by attribute with negative length. Nested sublists are supported.
  */
-#define SAFE_NETLINK_SEND(fd, nl_header, payload)		\
-	safe_netlink_send(__FILE__, __LINE__, fd, nl_header, payload)
-
-/** @private */
-static inline ssize_t 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);
-}
-
-/**
- * Receives a netlink message using safe_recvmsg().
- *
- * @param fd netlink socket file descriptor.
- * @param nl_header_buf buffer to contain the received netlink header structure.
- * @param buf_len The length of the header buffer. Must be greater than the page
- *                size.
+int tst_rtnl_add_attr_list(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, const struct tst_rtnl_attr_list *list);
+#define RTNL_ADD_ATTR_LIST(ctx, list) \
+	tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list))
+
+/* Check that all sent messages with NLM_F_ACK flag have been acked without
+ * error. Usage:
  *
- * @return The number of bytes received.
+ * tst_netlink_send(ctx);
+ * tst_netlink_wait(ctx);
+ * response = tst_netlink_recv(ctx);
+ * if (!tst_netlink_check_acks(ctx, response)) { ... }
+ * tst_netlink_free_message(response);
  */
-#define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len)			\
-	safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len)
+int tst_netlink_check_acks(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, struct tst_netlink_message *response);
+#define NETLINK_CHECK_ACKS(ctx, response) \
+	tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response))
 
 #endif /* TST_NETLINK_H */
diff --git a/include/tst_rtnetlink.h b/include/tst_rtnetlink.h
deleted file mode 100644
index c5f295a38..000000000
--- a/include/tst_rtnetlink.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright (c) 2021 Linux Test Project
- */
-
-#ifndef TST_RTNETLINK_H
-#define TST_RTNETLINK_H
-
-struct tst_netlink_context;
-
-struct tst_rtnl_attr_list {
-	unsigned short type;
-	const void *data;
-	ssize_t len;
-	const struct tst_rtnl_attr_list *sublist;
-};
-
-struct tst_netlink_message {
-	struct nlmsghdr *header;
-	struct nlmsgerr *err;
-	void *payload;
-	size_t payload_size;
-};
-
-extern int tst_netlink_errno;
-
-/* Open a netlink socket */
-struct tst_netlink_context *tst_netlink_create_context(const char *file,
-	const int lineno, int protocol);
-#define NETLINK_CREATE_CONTEXT(protocol) \
-	tst_netlink_create_context(__FILE__, __LINE__, (protocol))
-
-/* Free a tst_netlink_message array returned by tst_netlink_recv() */
-void tst_netlink_free_message(struct tst_netlink_message *msg);
-#define NETLINK_FREE_MESSAGE tst_netlink_free_message
-
-/* Close netlink socket */
-void tst_netlink_destroy_context(const char *file, const int lineno,
-	struct tst_netlink_context *ctx);
-#define NETLINK_DESTROY_CONTEXT(ctx) \
-	tst_netlink_destroy_context(__FILE__, __LINE__, (ctx))
-
-/* Send all messages in given buffer */
-int tst_netlink_send(const char *file, const int lineno,
-	struct tst_netlink_context *ctx);
-#define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx))
-
-/* Send all messages in given buffer and validate kernel response */
-int tst_netlink_send_validate(const char *file, const int lineno,
-	struct tst_netlink_context *ctx);
-#define NETLINK_SEND_VALIDATE(ctx) \
-	tst_netlink_send_validate(__FILE__, __LINE__, (ctx))
-
-/* Wait until data is available for reading from the netlink socket */
-int tst_netlink_wait(struct tst_netlink_context *ctx);
-#define NETLINK_WAIT tst_netlink_wait
-
-/*
- * Read from netlink socket and return an array of partially parsed messages.
- * header == NULL indicates end of array.
- */
-struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno,
-	struct tst_netlink_context *ctx);
-#define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx))
-
-/* Add new message to buffer */
-int tst_netlink_add_message(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, const struct nlmsghdr *header,
-	const void *payload, size_t payload_size);
-#define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \
-	tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \
-		(payload), (psize))
-
-/* Add arbitrary attribute to last message */
-int tst_rtnl_add_attr(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, unsigned short type, const void *data,
-	unsigned short len);
-#define RTNL_ADD_ATTR(ctx, type, data, len) \
-	tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
-
-/* Add string attribute to last message */
-int tst_rtnl_add_attr_string(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, unsigned short type, const char *data);
-#define RTNL_ADD_ATTR_STRING(ctx, type, data) \
-	tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
-
-/*
- * Add list of arbitrary attributes to last message. The list is terminated
- * by attribute with negative length. Nested sublists are supported.
- */
-int tst_rtnl_add_attr_list(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, const struct tst_rtnl_attr_list *list);
-#define RTNL_ADD_ATTR_LIST(ctx, list) \
-	tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list))
-
-/* Check that all sent messages with NLM_F_ACK flag have been acked without
- * error. Usage:
- *
- * tst_netlink_send(ctx);
- * tst_netlink_wait(ctx);
- * response = tst_netlink_recv(ctx);
- * if (!tst_netlink_check_acks(ctx, response)) { ... }
- * tst_netlink_free_message(response);
- */
-int tst_netlink_check_acks(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, struct tst_netlink_message *response);
-#define NETLINK_CHECK_ACKS(ctx, response) \
-	tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response))
-
-#endif /* TST_RTNETLINK_H */
diff --git a/lib/tst_crypto.c b/lib/tst_crypto.c
index c01632c2a..4495d0baa 100644
--- a/lib/tst_crypto.c
+++ b/lib/tst_crypto.c
@@ -10,102 +10,42 @@
 #define TST_NO_DEFAULT_MAIN
 #include "tst_test.h"
 #include "tst_crypto.h"
-#include "tst_netlink.h"
 
-void tst_crypto_open(struct tst_crypto_session *ses)
-{
-	const long ret = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO);
-
-	if (ret < 0 && errno == EPROTONOSUPPORT)
-		tst_brk(TCONF | TERRNO, "NETLINK_CRYPTO is probably disabled");
-
-	if (ret < 0) {
-		tst_brk(TBROK | TERRNO,
-			"socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
-	}
-
-	ses->fd = ret;
-	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)
-{
-	uint32_t len;
-	char buf[BUFSIZ];
-	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 ENODATA;
-}
-
-int tst_crypto_add_alg(struct tst_crypto_session *ses,
+int tst_crypto_add_alg(struct tst_netlink_context *ctx,
 		       const struct crypto_user_alg *alg)
 {
 	struct nlmsghdr nh = {
-		.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
 		.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);
-
-	return tst_crypto_recv_ack(ses);
+	NETLINK_ADD_MESSAGE(ctx, &nh, alg, sizeof(struct crypto_user_alg));
+	return NETLINK_SEND_VALIDATE(ctx) ? 0 : -tst_netlink_errno;
 }
 
-int tst_crypto_del_alg(struct tst_crypto_session *ses,
-		       const struct crypto_user_alg *alg)
+int tst_crypto_del_alg(struct tst_netlink_context *ctx,
+	const struct crypto_user_alg *alg, unsigned int retries)
 {
-	long ret;
+	int ret;
 	unsigned int i = 0;
 	struct nlmsghdr nh = {
-		.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
 		.nlmsg_type = CRYPTO_MSG_DELALG,
 		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
-		.nlmsg_pid = 0,
 	};
 
-	while (1) {
-		nh.nlmsg_seq = ++(ses->seq_num),
+	for (i = 0; i < retries; i++) {
+		NETLINK_ADD_MESSAGE(ctx, &nh, alg,
+			sizeof(struct crypto_user_alg));
 
-		SAFE_NETLINK_SEND(ses->fd, &nh, alg);
+		if (NETLINK_SEND_VALIDATE(ctx))
+			return 0;
 
-		ret = tst_crypto_recv_ack(ses);
-		if (ret != -EBUSY || i >= ses->retries)
-			break;
+		ret = -tst_netlink_errno;
 
-		if (usleep(1) && errno != EINTR)
-			tst_brk(TBROK | TERRNO, "usleep(1)");
+		if (ret != -EBUSY)
+			break;
 
-		++i;
+		usleep(1);
 	}
 
 	return ret;
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index 5873b3d58..6f86b8089 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -12,7 +12,7 @@
 
 #define TST_NO_DEFAULT_MAIN
 #include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
 #include "tst_netdevice.h"
 
 static struct tst_netlink_context *create_request(const char *file,
diff --git a/lib/tst_rtnetlink.c b/lib/tst_netlink.c
similarity index 99%
rename from lib/tst_rtnetlink.c
rename to lib/tst_netlink.c
index bf782ffb5..bd05df81a 100644
--- a/lib/tst_rtnetlink.c
+++ b/lib/tst_netlink.c
@@ -13,7 +13,7 @@
 #include <sys/poll.h>
 #define TST_NO_DEFAULT_MAIN
 #include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
 
 struct tst_netlink_context {
 	int socket;
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
index 0fd254a92..d441a2449 100644
--- a/testcases/cve/tcindex01.c
+++ b/testcases/cve/tcindex01.c
@@ -24,7 +24,7 @@
 #include <linux/pkt_sched.h>
 #include <linux/pkt_cls.h>
 #include "tst_test.h"
-#include "tst_rtnetlink.h"
+#include "tst_netlink.h"
 #include "tst_netdevice.h"
 #include "lapi/sched.h"
 #include "lapi/if_ether.h"
diff --git a/testcases/kernel/crypto/crypto_user01.c b/testcases/kernel/crypto/crypto_user01.c
index 47bf9f0d2..6f6036aed 100644
--- a/testcases/kernel/crypto/crypto_user01.c
+++ b/testcases/kernel/crypto/crypto_user01.c
@@ -17,7 +17,6 @@
 
 #include "tst_test.h"
 #include "tst_crypto.h"
-#include "tst_netlink.h"
 
 /*
  * include after <sys/socket.h> (via tst_test.h), to work around dependency bug
@@ -25,11 +24,11 @@
  */
 #include <linux/rtnetlink.h>
 
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
 
 static void setup(void)
 {
-	tst_crypto_open(&ses);
+	ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
 }
 
 static void do_check_for_leaks(const char *name, const char *value, size_t vlen)
@@ -131,25 +130,20 @@ static void validate_one_alg(const struct nlmsghdr *nh)
 	}
 }
 
-static void validate_alg_list(const void *buf, size_t remaining)
+static void validate_alg_list(const struct tst_netlink_message *msg)
 {
-	const struct nlmsghdr *nh;
-
-	for (nh = buf; NLMSG_OK(nh, remaining);
-	     nh = NLMSG_NEXT(nh, remaining)) {
-		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);
-		}
-		if (nh->nlmsg_type == NLMSG_DONE)
+	for (; msg->header; msg++) {
+		if (msg->header->nlmsg_type == NLMSG_DONE)
 			return;
-		if (nh->nlmsg_type != CRYPTO_MSG_GETALG) {
+
+		if (msg->header->nlmsg_type != CRYPTO_MSG_GETALG) {
 			tst_brk(TBROK,
 				"Unexpected message type; type=0x%hx, seq_num=%u",
-				nh->nlmsg_type, nh->nlmsg_seq);
+				msg->header->nlmsg_type,
+				msg->header->nlmsg_seq);
 		}
-		validate_one_alg(nh);
+
+		validate_one_alg(msg->header);
 	}
 }
 
@@ -157,35 +151,23 @@ static void run(void)
 {
 	struct crypto_user_alg payload = { 0 };
 	struct nlmsghdr nh = {
-		.nlmsg_len = sizeof(payload),
 		.nlmsg_type = CRYPTO_MSG_GETALG,
 		.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
-		.nlmsg_seq = ++(ses.seq_num),
-		.nlmsg_pid = 0,
 	};
-	/*
-	 * Due to an apparent kernel bug, this API cannot be used incrementally,
-	 * so we just use a large recvmsg() buffer.  This is good enough since
-	 * we don't necessarily have to check every algorithm for this test to
-	 * be effective...
-	 */
-	const size_t bufsize = 1048576;
-	void *buf = SAFE_MALLOC(bufsize);
-	size_t res;
-
-	SAFE_NETLINK_SEND(ses.fd, &nh, &payload);
-
-	res = SAFE_NETLINK_RECV(ses.fd, buf, bufsize);
-
-	validate_alg_list(buf, res);
-
-	free(buf);
+	struct tst_netlink_message *msg;
+
+	NETLINK_ADD_MESSAGE(ctx, &nh, &payload, sizeof(payload));
+	NETLINK_SEND(ctx);
+	NETLINK_WAIT(ctx);
+	msg = NETLINK_RECV(ctx);
+	validate_alg_list(msg);
+	NETLINK_FREE_MESSAGE(msg);
 	tst_res(TPASS, "No information leaks found");
 }
 
 static void cleanup(void)
 {
-	tst_crypto_close(&ses);
+	NETLINK_DESTROY_CONTEXT(ctx);
 }
 
 static struct tst_test test = {
diff --git a/testcases/kernel/crypto/crypto_user02.c b/testcases/kernel/crypto/crypto_user02.c
index afaff5d18..89cbb9bc5 100644
--- a/testcases/kernel/crypto/crypto_user02.c
+++ b/testcases/kernel/crypto/crypto_user02.c
@@ -52,7 +52,7 @@ static const char * const ALGORITHM_CANDIDATES[] = {
 };
 
 static const char* algorithm = NULL;
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
 
 
 static void setup(void)
@@ -60,7 +60,8 @@ static void setup(void)
 	int rc;
 	unsigned i;
 	struct crypto_user_alg alg;
-	tst_crypto_open(&ses);
+
+	ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
 
 	/* find an algorithm, that is not in use */
 	for (i = 0; i < ARRAY_SIZE(ALGORITHM_CANDIDATES); ++i) {
@@ -68,12 +69,12 @@ static void setup(void)
 		strcpy(alg.cru_driver_name, ALGORITHM_CANDIDATES[i]);
 
 		/* try to add it, to see if it is valid */
-		rc = tst_crypto_add_alg(&ses, &alg);
+		rc = tst_crypto_add_alg(ctx, &alg);
 		if (rc != 0)
 			continue;
 
 		/* it also has to be deletable */
-		rc = tst_crypto_del_alg(&ses, &alg);
+		rc = tst_crypto_del_alg(ctx, &alg, 1000);
 		if (rc == 0) {
 			algorithm = ALGORITHM_CANDIDATES[i];
 			break;
@@ -103,9 +104,9 @@ static void run(void)
 
 		if (pid == 0) {
 			/* Child process: execute CRYPTO_MSG_NEWALG. */
-			tst_crypto_open(&ses);
+			ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
 			for (;;) {
-				TEST(tst_crypto_add_alg(&ses, &alg));
+				TEST(tst_crypto_add_alg(ctx, &alg));
 				if (TST_RET && TST_RET != -EEXIST)
 					tst_brk(TBROK | TRERRNO,
 						"unexpected error from tst_crypto_add_alg()");
@@ -123,7 +124,7 @@ static void run(void)
 		SAFE_WAIT(&status);
 		if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL)
 			tst_brk(TBROK, "child %s", tst_strstatus(status));
-		TEST(tst_crypto_del_alg(&ses, &alg));
+		TEST(tst_crypto_del_alg(ctx, &alg, 1000));
 		if (TST_RET && TST_RET != -ENOENT)
 			tst_brk(TBROK | TRERRNO,
 				"unexpected error from tst_crypto_del_alg()");
@@ -134,7 +135,7 @@ static void run(void)
 
 static void cleanup(void)
 {
-	tst_crypto_close(&ses);
+	NETLINK_DESTROY_CONTEXT(ctx);
 }
 
 static struct tst_test test = {
diff --git a/testcases/kernel/crypto/pcrypt_aead01.c b/testcases/kernel/crypto/pcrypt_aead01.c
index 3b4f5d8d1..3979f317a 100644
--- a/testcases/kernel/crypto/pcrypt_aead01.c
+++ b/testcases/kernel/crypto/pcrypt_aead01.c
@@ -26,11 +26,11 @@
 
 #define ATTEMPTS 10000
 
-static struct tst_crypto_session ses = TST_CRYPTO_SESSION_INIT;
+static struct tst_netlink_context *ctx;
 
 void setup(void)
 {
-	tst_crypto_open(&ses);
+	ctx = NETLINK_CREATE_CONTEXT(NETLINK_CRYPTO);
 }
 
 void run(void)
@@ -43,7 +43,7 @@ void run(void)
 	};
 
 	for (i = 0; i < ATTEMPTS; ++i) {
-		TEST(tst_crypto_add_alg(&ses, &a));
+		TEST(tst_crypto_add_alg(ctx, &a));
 		if (TST_RET && TST_RET == -ENOENT) {
 			tst_brk(TCONF | TRERRNO,
 				"pcrypt, hmac, sha256, cbc or aes not supported");
@@ -51,7 +51,7 @@ void run(void)
 		if (TST_RET && TST_RET != -EEXIST)
 			tst_brk(TBROK | TRERRNO, "add_alg");
 
-		TEST(tst_crypto_del_alg(&ses, &a));
+		TEST(tst_crypto_del_alg(ctx, &a, 1000));
 		if (TST_RET)
 			tst_brk(TBROK | TRERRNO, "del_alg");
 
@@ -67,7 +67,7 @@ void run(void)
 
 void cleanup(void)
 {
-	tst_crypto_close(&ses);
+	NETLINK_DESTROY_CONTEXT(ctx);
 }
 
 static struct tst_test test = {
-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 4/5] tst_netlink: Add helper functions for handling generic attributes
  2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
                   ` (2 preceding siblings ...)
  2023-11-14 12:31 ` [LTP] [PATCH v2 3/5] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
@ 2023-11-14 12:31 ` Martin Doucha
  2023-11-14 12:31 ` [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248 Martin Doucha
  4 siblings, 0 replies; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

Refactor struct tst_rtnl_attr_list for generic use and add helper
functions for handling generic struct nlattr message attributes.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---

Changes since v1: New patch

 include/tst_netdevice.h   |  6 +--
 include/tst_netlink.h     | 38 ++++++++++++++----
 lib/tst_netdevice.c       | 20 +++++-----
 lib/tst_netlink.c         | 82 ++++++++++++++++++++++++++++++++++++++-
 testcases/cve/tcindex01.c | 12 +++---
 5 files changed, 131 insertions(+), 27 deletions(-)

diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h
index 4239d0960..8d40148a6 100644
--- a/include/tst_netdevice.h
+++ b/include/tst_netdevice.h
@@ -132,7 +132,7 @@ int tst_netdev_remove_route_inet(const char *file, const int lineno,
 int tst_netdev_add_qdisc(const char *file, const int lineno, int strict,
 	const char *ifname, unsigned int family, unsigned int parent,
 	unsigned int handle, const char *qd_kind,
-	const struct tst_rtnl_attr_list *config);
+	const struct tst_netlink_attr_list *config);
 #define NETDEV_ADD_QDISC(ifname, family, parent, handle, qd_kind, config) \
 	tst_netdev_add_qdisc(__FILE__, __LINE__, 1, (ifname), (family), \
 		(parent), (handle), (qd_kind), (config))
@@ -154,7 +154,7 @@ int tst_netdev_remove_qdisc(const char *file, const int lineno, int strict,
 int tst_netdev_add_traffic_class(const char *file, const int lineno,
 	int strict, const char *ifname, unsigned int parent,
 	unsigned int handle, const char *qd_kind,
-	const struct tst_rtnl_attr_list *config);
+	const struct tst_netlink_attr_list *config);
 #define NETDEV_ADD_TRAFFIC_CLASS(ifname, parent, handle, qd_kind, config) \
 	tst_netdev_add_traffic_class(__FILE__, __LINE__, 1, (ifname), \
 		(parent), (handle), (qd_kind), (config))
@@ -173,7 +173,7 @@ int tst_netdev_remove_traffic_class(const char *file, const int lineno,
 int tst_netdev_add_traffic_filter(const char *file, const int lineno,
 	int strict, const char *ifname, unsigned int parent,
 	unsigned int handle, unsigned int protocol, unsigned int priority,
-	const char *f_kind, const struct tst_rtnl_attr_list *config);
+	const char *f_kind, const struct tst_netlink_attr_list *config);
 #define NETDEV_ADD_TRAFFIC_FILTER(ifname, parent, handle, protocol, priority, \
 	f_kind, config) \
 	tst_netdev_add_traffic_filter(__FILE__, __LINE__, 1, (ifname), \
diff --git a/include/tst_netlink.h b/include/tst_netlink.h
index f10f1cf5d..7d96fd711 100644
--- a/include/tst_netlink.h
+++ b/include/tst_netlink.h
@@ -9,11 +9,11 @@
 
 struct tst_netlink_context;
 
-struct tst_rtnl_attr_list {
+struct tst_netlink_attr_list {
 	unsigned short type;
 	const void *data;
 	ssize_t len;
-	const struct tst_rtnl_attr_list *sublist;
+	const struct tst_netlink_attr_list *sublist;
 };
 
 struct tst_netlink_message {
@@ -72,25 +72,49 @@ int tst_netlink_add_message(const char *file, const int lineno,
 	tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \
 		(payload), (psize))
 
-/* Add arbitrary attribute to last message */
+/* Add arbitrary nlattr attribute to last message */
+int tst_netlink_add_attr(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type, const void *data,
+	unsigned short len);
+#define NETLINK_ADD_ATTR(ctx, type, data, len) \
+	tst_netlink_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
+
+/* Add string nlattr attribute to last message */
+int tst_netlink_add_attr_string(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type, const char *data);
+#define NETLINK_ADD_ATTR_STRING(ctx, type, data) \
+	tst_netlink_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
+
+/*
+ * Add list of arbitrary nlattr attributes to last message. The list is
+ * terminated by attribute with negative length. Nested sublists are supported.
+ */
+int tst_netlink_add_attr_list(const char *file, const int lineno,
+	struct tst_netlink_context *ctx,
+	const struct tst_netlink_attr_list *list);
+#define NETLINK_ADD_ATTR_LIST(ctx, list) \
+	tst_netlink_add_attr_list(__FILE__, __LINE__, (ctx), (list))
+
+/* Add arbitrary rtattr attribute to last message */
 int tst_rtnl_add_attr(const char *file, const int lineno,
 	struct tst_netlink_context *ctx, unsigned short type, const void *data,
 	unsigned short len);
 #define RTNL_ADD_ATTR(ctx, type, data, len) \
 	tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len))
 
-/* Add string attribute to last message */
+/* Add string rtattr attribute to last message */
 int tst_rtnl_add_attr_string(const char *file, const int lineno,
 	struct tst_netlink_context *ctx, unsigned short type, const char *data);
 #define RTNL_ADD_ATTR_STRING(ctx, type, data) \
 	tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data))
 
 /*
- * Add list of arbitrary attributes to last message. The list is terminated
- * by attribute with negative length. Nested sublists are supported.
+ * Add list of arbitrary rtattr attributes to last message. The list is
+ * terminated by attribute with negative length. Nested sublists are supported.
  */
 int tst_rtnl_add_attr_list(const char *file, const int lineno,
-	struct tst_netlink_context *ctx, const struct tst_rtnl_attr_list *list);
+	struct tst_netlink_context *ctx,
+	const struct tst_netlink_attr_list *list);
 #define RTNL_ADD_ATTR_LIST(ctx, list) \
 	tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list))
 
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index 6f86b8089..1042466bf 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -105,17 +105,17 @@ int tst_create_veth_pair(const char *file, const int lineno, int strict,
 	int ret;
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
 	struct tst_netlink_context *ctx;
-	struct tst_rtnl_attr_list peerinfo[] = {
+	struct tst_netlink_attr_list peerinfo[] = {
 		{IFLA_IFNAME, ifname2, strlen(ifname2) + 1, NULL},
 		{0, NULL, -1, NULL}
 	};
-	struct tst_rtnl_attr_list peerdata[] = {
+	struct tst_netlink_attr_list peerdata[] = {
 		{VETH_INFO_PEER, &info, sizeof(info), peerinfo},
 		{0, NULL, -1, NULL}
 	};
-	struct tst_rtnl_attr_list attrs[] = {
+	struct tst_netlink_attr_list attrs[] = {
 		{IFLA_IFNAME, ifname1, strlen(ifname1) + 1, NULL},
-		{IFLA_LINKINFO, NULL, 0, (const struct tst_rtnl_attr_list[]){
+		{IFLA_LINKINFO, NULL, 0, (const struct tst_netlink_attr_list[]){
 			{IFLA_INFO_KIND, "veth", 4, NULL},
 			{IFLA_INFO_DATA, NULL, 0, peerdata},
 			{0, NULL, -1, NULL}
@@ -164,9 +164,9 @@ int tst_netdev_add_device(const char *file, const int lineno, int strict,
 	int ret;
 	struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
 	struct tst_netlink_context *ctx;
-	struct tst_rtnl_attr_list attrs[] = {
+	struct tst_netlink_attr_list attrs[] = {
 		{IFLA_IFNAME, ifname, strlen(ifname) + 1, NULL},
-		{IFLA_LINKINFO, NULL, 0, (const struct tst_rtnl_attr_list[]){
+		{IFLA_LINKINFO, NULL, 0, (const struct tst_netlink_attr_list[]){
 			{IFLA_INFO_KIND, devtype, strlen(devtype), NULL},
 			{0, NULL, -1, NULL}
 		}},
@@ -527,7 +527,7 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
 	const char *object, unsigned int action, unsigned int nl_flags,
 	const char *ifname, unsigned int family, unsigned int parent,
 	unsigned int handle, unsigned int info, const char *qd_kind,
-	const struct tst_rtnl_attr_list *config)
+	const struct tst_netlink_attr_list *config)
 {
 	struct tst_netlink_context *ctx;
 	int ret;
@@ -585,7 +585,7 @@ static int modify_qdisc(const char *file, const int lineno, int strict,
 int tst_netdev_add_qdisc(const char *file, const int lineno, int strict,
 	const char *ifname, unsigned int family, unsigned int parent,
 	unsigned int handle, const char *qd_kind,
-	const struct tst_rtnl_attr_list *config)
+	const struct tst_netlink_attr_list *config)
 {
 	return modify_qdisc(file, lineno, strict, "queueing discipline",
 		RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, ifname, family,
@@ -604,7 +604,7 @@ int tst_netdev_remove_qdisc(const char *file, const int lineno, int strict,
 int tst_netdev_add_traffic_class(const char *file, const int lineno,
 	int strict, const char *ifname, unsigned int parent,
 	unsigned int handle, const char *qd_kind,
-	const struct tst_rtnl_attr_list *config)
+	const struct tst_netlink_attr_list *config)
 {
 	return modify_qdisc(file, lineno, strict, "traffic class",
 		RTM_NEWTCLASS, NLM_F_CREATE | NLM_F_EXCL, ifname, AF_UNSPEC,
@@ -623,7 +623,7 @@ int tst_netdev_remove_traffic_class(const char *file, const int lineno,
 int tst_netdev_add_traffic_filter(const char *file, const int lineno,
 	int strict, const char *ifname, unsigned int parent,
 	unsigned int handle, unsigned int protocol, unsigned int priority,
-	const char *f_kind, const struct tst_rtnl_attr_list *config)
+	const char *f_kind, const struct tst_netlink_attr_list *config)
 {
 	return modify_qdisc(file, lineno, strict, "traffic filter",
 		RTM_NEWTFILTER, NLM_F_CREATE | NLM_F_EXCL, ifname, AF_UNSPEC,
diff --git a/lib/tst_netlink.c b/lib/tst_netlink.c
index bd05df81a..7bc98af56 100644
--- a/lib/tst_netlink.c
+++ b/lib/tst_netlink.c
@@ -283,6 +283,86 @@ int tst_netlink_add_message(const char *file, const int lineno,
 	return 1;
 }
 
+int tst_netlink_add_attr(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type,
+	const void *data, unsigned short len)
+{
+	size_t size = NLA_HDRLEN + NLA_ALIGN(len);
+	struct nlattr *attr;
+
+	if (!ctx->curmsg) {
+		tst_brk_(file, lineno, TBROK,
+			"%s(): No message to add attributes to", __func__);
+		return 0;
+	}
+
+	if (!netlink_grow_buffer(file, lineno, ctx, size))
+		return 0;
+
+	size = NLMSG_ALIGN(ctx->curmsg->nlmsg_len);
+	attr = (struct nlattr *)(((char *)ctx->curmsg) + size);
+	attr->nla_type = type;
+	attr->nla_len = NLA_HDRLEN + len;
+	memcpy(((char *)attr) + NLA_HDRLEN, data, len);
+	ctx->curmsg->nlmsg_len = size + attr->nla_len;
+	ctx->datalen = NLMSG_ALIGN(ctx->datalen) + attr->nla_len;
+
+	return 1;
+}
+
+int tst_netlink_add_attr_string(const char *file, const int lineno,
+	struct tst_netlink_context *ctx, unsigned short type,
+	const char *data)
+{
+	return tst_netlink_add_attr(file, lineno, ctx, type, data,
+		strlen(data) + 1);
+}
+
+int tst_netlink_add_attr_list(const char *file, const int lineno,
+	struct tst_netlink_context *ctx,
+	const struct tst_netlink_attr_list *list)
+{
+	int i, ret;
+	size_t offset;
+
+	for (i = 0; list[i].len >= 0; i++) {
+		if (list[i].len > USHRT_MAX) {
+			tst_brk_(file, lineno, TBROK,
+				"%s(): Attribute value too long", __func__);
+			return -1;
+		}
+
+		offset = NLMSG_ALIGN(ctx->datalen);
+		ret = tst_netlink_add_attr(file, lineno, ctx, list[i].type,
+			list[i].data, list[i].len);
+
+		if (!ret)
+			return -1;
+
+		if (list[i].sublist) {
+			struct rtattr *attr;
+
+			ret = tst_netlink_add_attr_list(file, lineno, ctx,
+				list[i].sublist);
+
+			if (ret < 0)
+				return ret;
+
+			attr = (struct rtattr *)(ctx->buffer + offset);
+
+			if (ctx->datalen - offset > USHRT_MAX) {
+				tst_brk_(file, lineno, TBROK,
+					"%s(): Sublist too long", __func__);
+				return -1;
+			}
+
+			attr->rta_len = ctx->datalen - offset;
+		}
+	}
+
+	return i;
+}
+
 int tst_rtnl_add_attr(const char *file, const int lineno,
 	struct tst_netlink_context *ctx, unsigned short type,
 	const void *data, unsigned short len)
@@ -320,7 +400,7 @@ int tst_rtnl_add_attr_string(const char *file, const int lineno,
 
 int tst_rtnl_add_attr_list(const char *file, const int lineno,
 	struct tst_netlink_context *ctx,
-	const struct tst_rtnl_attr_list *list)
+	const struct tst_netlink_attr_list *list)
 {
 	int i, ret;
 	size_t offset;
diff --git a/testcases/cve/tcindex01.c b/testcases/cve/tcindex01.c
index d441a2449..b4f2bb01a 100644
--- a/testcases/cve/tcindex01.c
+++ b/testcases/cve/tcindex01.c
@@ -46,15 +46,15 @@ static const struct tc_htb_glob qd_opt = {
 static struct tc_htb_opt cls_opt = {};
 
 /* htb qdisc and class options */
-static const struct tst_rtnl_attr_list qd_config[] = {
-	{TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+static const struct tst_netlink_attr_list qd_config[] = {
+	{TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
 		{TCA_HTB_INIT, &qd_opt, sizeof(qd_opt), NULL},
 		{0, NULL, -1, NULL}
 	}},
 	{0, NULL, -1, NULL}
 };
-static const struct tst_rtnl_attr_list cls_config[] = {
-	{TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+static const struct tst_netlink_attr_list cls_config[] = {
+	{TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
 		{TCA_HTB_PARMS, &cls_opt, sizeof(cls_opt), NULL},
 		{0, NULL, -1, NULL}
 	}},
@@ -62,8 +62,8 @@ static const struct tst_rtnl_attr_list cls_config[] = {
 };
 
 /* tcindex filter options */
-static const struct tst_rtnl_attr_list f_config[] = {
-	{TCA_OPTIONS, NULL, 0, (const struct tst_rtnl_attr_list[]){
+static const struct tst_netlink_attr_list f_config[] = {
+	{TCA_OPTIONS, NULL, 0, (const struct tst_netlink_attr_list[]){
 		{TCA_TCINDEX_MASK, &mask, sizeof(mask), NULL},
 		{TCA_TCINDEX_SHIFT, &shift, sizeof(shift), NULL},
 		{TCA_TCINDEX_CLASSID, &clsid, sizeof(clsid), NULL},
-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
                   ` (3 preceding siblings ...)
  2023-11-14 12:31 ` [LTP] [PATCH v2 4/5] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
@ 2023-11-14 12:31 ` Martin Doucha
  2023-11-14 15:39   ` Petr Vorel
  4 siblings, 1 reply; 13+ messages in thread
From: Martin Doucha @ 2023-11-14 12:31 UTC (permalink / raw)
  To: Petr Vorel, ltp

Fixes #1058

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---

Changes since v1: New patch

 testcases/network/iptables/Makefile |   2 +-
 testcases/network/iptables/nft02.c  | 211 ++++++++++++++++++++++++++++
 2 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 testcases/network/iptables/nft02.c

diff --git a/testcases/network/iptables/Makefile b/testcases/network/iptables/Makefile
index 1b42f25db..02e228cbc 100644
--- a/testcases/network/iptables/Makefile
+++ b/testcases/network/iptables/Makefile
@@ -5,7 +5,7 @@
 
 top_srcdir		?= ../../..
 
-include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/testcases.mk
 
 INSTALL_TARGETS		:= *.sh
 
diff --git a/testcases/network/iptables/nft02.c b/testcases/network/iptables/nft02.c
new file mode 100644
index 000000000..4cea7ce64
--- /dev/null
+++ b/testcases/network/iptables/nft02.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC
+ * Author: Marcos Paulo de Souza <mpdesouza@suse.com>
+ * LTP port: Martin Doucha <mdoucha@suse.cz>
+ */
+
+/*\
+ * CVE-2023-31248
+ *
+ * Test for use-after-free when adding a new rule to a chain deleted
+ * in the same netlink message batch.
+ *
+ * Kernel bug fixed in:
+ *
+ *  commit 515ad530795c118f012539ed76d02bacfd426d89
+ *  Author: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+ *  Date:   Wed Jul 5 09:12:55 2023 -0300
+ *
+ *  netfilter: nf_tables: do not ignore genmask when looking up chain by id
+ */
+
+#include <linux/netlink.h>
+#include <linux/tcp.h>
+#include <arpa/inet.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nfnetlink.h>
+#include "tst_test.h"
+#include "tst_netlink.h"
+
+#define TABNAME "ltp_table1"
+#define CHAINNAME "ltp_chain1"
+
+static const uint8_t rule_proto = IPPROTO_TCP;
+static const uint32_t rule_dport = 80;
+
+static uint32_t chain_id;
+static uint32_t cmp_sreg;
+static uint32_t cmp_op;
+static struct tst_netlink_context *ctx;
+
+/* Table creation config */
+static const struct tst_netlink_attr_list table_config[] = {
+	{NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
+	{0, NULL, -1, NULL}
+};
+
+/* Chain creation and deletion config */
+static const struct tst_netlink_attr_list newchain_config[] = {
+	{NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
+	{NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
+	{NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
+	{0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list delchain_config[] = {
+	{NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
+	{NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
+	{0, NULL, -1, NULL}
+};
+
+/* Rule creation config */
+static const struct tst_netlink_attr_list rule_data_config1[] = {
+	{NFTA_CMP_SREG, &cmp_sreg, sizeof(cmp_sreg), NULL},
+	{NFTA_CMP_OP, &cmp_op, sizeof(cmp_op), NULL},
+	{NFTA_CMP_DATA, NULL, 0, (const struct tst_netlink_attr_list[]) {
+		{NFTA_DATA_VALUE, &rule_proto, sizeof(rule_proto), NULL},
+		{0, NULL, -1, NULL}
+	}},
+	{0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list rule_data_config2[] = {
+	{NFTA_CMP_SREG, &cmp_sreg, sizeof(cmp_sreg), NULL},
+	{NFTA_CMP_OP, &cmp_op, sizeof(cmp_op), NULL},
+	{NFTA_CMP_DATA, NULL, 0, (const struct tst_netlink_attr_list[]) {
+		{NFTA_DATA_VALUE, &rule_dport, sizeof(rule_dport), NULL},
+		{0, NULL, -1, NULL}
+	}},
+	{0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list rule_expr_config[] = {
+	{NFTA_LIST_ELEM, NULL, 0, (const struct tst_netlink_attr_list[]) {
+		{NFTA_EXPR_NAME, "cmp", 4, NULL},
+		{NFTA_EXPR_DATA, NULL, 0, rule_data_config1},
+		{0, NULL, -1, NULL}
+	}},
+	{NFTA_LIST_ELEM, NULL, 0, (const struct tst_netlink_attr_list[]) {
+		{NFTA_EXPR_NAME, "cmp", 4, NULL},
+		{NFTA_EXPR_DATA, NULL, 0, rule_data_config2},
+		{0, NULL, -1, NULL}
+	}},
+	{0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list rule_config[] = {
+	{NFTA_RULE_EXPRESSIONS, NULL, 0, rule_expr_config},
+	{NFTA_RULE_TABLE, TABNAME, strlen(TABNAME) + 1, NULL},
+	{NFTA_RULE_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
+	{0, NULL, -1, NULL}
+};
+
+static void setup(void)
+{
+	tst_setup_netns();
+
+	chain_id = htonl(77);
+	cmp_sreg = htonl(NFT_REG_1);
+	cmp_op = htonl(NFT_CMP_EQ);
+}
+
+static void run(void)
+{
+	struct nlmsghdr header;
+	struct nfgenmsg nfpayload;
+
+	memset(&header, 0, sizeof(header));
+	memset(&nfpayload, 0, sizeof(nfpayload));
+	nfpayload.version = NFNETLINK_V0;
+
+	ctx = NETLINK_CREATE_CONTEXT(NETLINK_NETFILTER);
+
+	/* Start netfilter batch */
+	header.nlmsg_type = NFNL_MSG_BATCH_BEGIN;
+	header.nlmsg_flags = NLM_F_REQUEST;
+	nfpayload.nfgen_family = AF_UNSPEC;
+	nfpayload.res_id = htons(NFNL_SUBSYS_NFTABLES);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+
+	/* Add table */
+	header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWTABLE;
+	header.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+	nfpayload.nfgen_family = NFPROTO_IPV4;
+	nfpayload.res_id = htons(0);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+	NETLINK_ADD_ATTR_LIST(ctx, table_config);
+
+	/* Add chain */
+	header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWCHAIN;
+	header.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+	nfpayload.nfgen_family = NFPROTO_IPV4;
+	nfpayload.res_id = htons(0);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+	NETLINK_ADD_ATTR_LIST(ctx, newchain_config);
+
+	/* Delete the above chain */
+	header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_DELCHAIN;
+	header.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	nfpayload.nfgen_family = NFPROTO_IPV4;
+	nfpayload.res_id = htons(0);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+	NETLINK_ADD_ATTR_LIST(ctx, delchain_config);
+
+	/* Add rule to deleted chain */
+	header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWRULE;
+	header.nlmsg_flags = NLM_F_REQUEST | NLM_F_APPEND | NLM_F_CREATE |
+		NLM_F_ACK;
+	nfpayload.nfgen_family = NFPROTO_IPV4;
+	nfpayload.res_id = htons(0);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+	NETLINK_ADD_ATTR_LIST(ctx, rule_config);
+
+	/* End batch */
+	header.nlmsg_type = NFNL_MSG_BATCH_END;
+	header.nlmsg_flags = NLM_F_REQUEST;
+	nfpayload.nfgen_family = AF_UNSPEC;
+	nfpayload.res_id = htons(NFNL_SUBSYS_NFTABLES);
+	NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+
+	NETLINK_SEND_VALIDATE(ctx);
+	NETLINK_DESTROY_CONTEXT(ctx);
+	ctx = NULL;
+
+	/* Wait for kernel page fault error */
+	usleep(100000);
+
+	if (tst_taint_check()) {
+		tst_res(TFAIL, "Kernel is vulnerable");
+		return;
+	}
+
+	tst_res(TPASS, "Nothing bad happened, probably");
+}
+
+static void cleanup(void)
+{
+	NETLINK_DESTROY_CONTEXT(ctx);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.taint_check = TST_TAINT_W | TST_TAINT_D,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_USER_NS=y",
+		"CONFIG_NF_TABLES",
+		NULL
+	},
+	.save_restore = (const struct tst_path_val[]) {
+		{"/proc/sys/user/max_user_namespaces", "1024", TST_SR_SKIP},
+		{}
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "515ad530795c"},
+		{"CVE", "2023-31248"},
+		{}
+	}
+};
-- 
2.42.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-14 12:31 ` [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248 Martin Doucha
@ 2023-11-14 15:39   ` Petr Vorel
  2023-11-15  7:43     ` 河原颯太
  0 siblings, 1 reply; 13+ messages in thread
From: Petr Vorel @ 2023-11-14 15:39 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

...
> +++ b/testcases/network/iptables/nft02.c
...
> +/* Chain creation and deletion config */
> +static const struct tst_netlink_attr_list newchain_config[] = {
> +	{NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
> +	{NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
> +	{NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},

Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?

Otherwise the patchset looks ok.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use
  2023-11-14 12:31 ` [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
@ 2023-11-14 19:14   ` Petr Vorel
  0 siblings, 0 replies; 13+ messages in thread
From: Petr Vorel @ 2023-11-14 19:14 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

...
> -3 rtnetlink API
> +3 Netlink API
>  ---------------
I fixed formatting (this must be shorter: ------------)
and merged the first 3 commits.

Thanks!

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-14 15:39   ` Petr Vorel
@ 2023-11-15  7:43     ` 河原颯太
  2023-11-15  8:23       ` Petr Vorel
  2023-11-15 17:34       ` Martin Doucha
  0 siblings, 2 replies; 13+ messages in thread
From: 河原颯太 @ 2023-11-15  7:43 UTC (permalink / raw)
  To: Petr Vorel, Martin Doucha; +Cc: ltp

Hi Martin, Petr.


2023年11月15日(水) 0:39 Petr Vorel <pvorel@suse.cz>:
>
> Hi Martin,
>
> ...
> > +++ b/testcases/network/iptables/nft02.c
> ...
> > +/* Chain creation and deletion config */
> > +static const struct tst_netlink_attr_list newchain_config[] = {
> > +     {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
> > +     {NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
> > +     {NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
>
> Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
> for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?

It was the same on RHEL8 (and/or other clone OS).

And, I would like to see this test added to runtest/cve and .gitignore.

> +       if (tst_taint_check()) {
> +               tst_res(TFAIL, "Kernel is vulnerable");
> +               return;
> +       }

Not a problem with the test itself but, If TAINT_W was already set,
the test report TPASS by misstake.
Below patch masks TAINT_W if that taint flag was set before test started.

commit de9b5c2636204ab06dbb3c7dc57296d73ac572ac
Author: Jan Stancek <jstancek@redhat.com>
Date:   Tue Apr 21 14:15:48 2020 +0200

    lib: tst_taint: Ignore WARN taint flag if already set

    This commit changes the library so that it ignores the taint warn flag
    if it was set prior to the test run. It turns out that the warn taint
    flag is not well defined and could be easily set on a freshly booted
    kernel for example when buggy BIOS is detected.

    Other recent example is disabling ip forward on kvm guests:
      https://github.com/containers/libpod/issues/5815
      https://lore.kernel.org/netdev/a47b6a3b-c064-2f53-7cf6-d0d0720e9d99@redhat.com/

    Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
    Signed-off-by: Jan Stancek <jstancek@redhat.com>
    Cc: Chang Yin <cyin@redhat.com>
    Reviewed-by: Li Wang <liwang@redhat.com>

diff --git a/lib/tst_taint.c b/lib/tst_taint.c
index a5dbf77d2..49146aacb 100644
--- a/lib/tst_taint.c
+++ b/lib/tst_taint.c
@@ -82,9 +82,14 @@ void tst_taint_init(unsigned int mask)
                tst_res(TCONF, "Kernel is too old for requested mask");

        taint_mask = mask;
-
        taint = tst_taint_read();
-       if ((taint & mask) != 0)
+
+       if (taint & TST_TAINT_W) {
+               tst_res(TCONF, "Ignoring already set kernel warning taint");
+               taint_mask &= ~TST_TAINT_W;
+       }
+
+       if ((taint & taint_mask) != 0)
                tst_brk(TBROK, "Kernel is already tainted: %u", taint);
 }

Other tests rely on TAINT_W to decide the result also report TPASS by
misstake if TAINT_W was already set.
In my patch v1 about CVE-2023-31248 check error == ENOENT. In this
case, test reports correct result.
It may be difficult to implement test like patch v1 using the internal
tst_netlink API, but we should be aware of this issue.

Best regards.
Souta Kawahara <souta.kawahara@miraclelinux.com>


>
> Otherwise the patchset looks ok.
>
> Kind regards,
> Petr
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-15  7:43     ` 河原颯太
@ 2023-11-15  8:23       ` Petr Vorel
  2023-11-15  9:16         ` Jan Stancek
  2023-11-15 17:34       ` Martin Doucha
  1 sibling, 1 reply; 13+ messages in thread
From: Petr Vorel @ 2023-11-15  8:23 UTC (permalink / raw)
  To: 河原颯太; +Cc: ltp

> Hi Martin, Petr.


> 2023年11月15日(水) 0:39 Petr Vorel <pvorel@suse.cz>:

> > Hi Martin,

> > ...
> > > +++ b/testcases/network/iptables/nft02.c
> > ...
> > > +/* Chain creation and deletion config */
> > > +static const struct tst_netlink_attr_list newchain_config[] = {
> > > +     {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
> > > +     {NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
> > > +     {NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},

> > Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
> > for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?

> It was the same on RHEL8 (and/or other clone OS).

> And, I would like to see this test added to runtest/cve and .gitignore.

Good point, thanks. Maybe it could be also in runtest/net.tcp_cmds.

> > +       if (tst_taint_check()) {
> > +               tst_res(TFAIL, "Kernel is vulnerable");
> > +               return;
> > +       }

> Not a problem with the test itself but, If TAINT_W was already set,
> the test report TPASS by misstake.
> Below patch masks TAINT_W if that taint flag was set before test started.

> commit de9b5c2636204ab06dbb3c7dc57296d73ac572ac
> Author: Jan Stancek <jstancek@redhat.com>
> Date:   Tue Apr 21 14:15:48 2020 +0200

>     lib: tst_taint: Ignore WARN taint flag if already set

>     This commit changes the library so that it ignores the taint warn flag
>     if it was set prior to the test run. It turns out that the warn taint
>     flag is not well defined and could be easily set on a freshly booted
>     kernel for example when buggy BIOS is detected.

>     Other recent example is disabling ip forward on kvm guests:
>       https://github.com/containers/libpod/issues/5815
>       https://lore.kernel.org/netdev/a47b6a3b-c064-2f53-7cf6-d0d0720e9d99@redhat.com/

>     Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
>     Signed-off-by: Jan Stancek <jstancek@redhat.com>
>     Cc: Chang Yin <cyin@redhat.com>
>     Reviewed-by: Li Wang <liwang@redhat.com>

> diff --git a/lib/tst_taint.c b/lib/tst_taint.c
> index a5dbf77d2..49146aacb 100644
> --- a/lib/tst_taint.c
> +++ b/lib/tst_taint.c
> @@ -82,9 +82,14 @@ void tst_taint_init(unsigned int mask)
>                 tst_res(TCONF, "Kernel is too old for requested mask");

>         taint_mask = mask;
> -
>         taint = tst_taint_read();
> -       if ((taint & mask) != 0)
> +
> +       if (taint & TST_TAINT_W) {
> +               tst_res(TCONF, "Ignoring already set kernel warning taint");
> +               taint_mask &= ~TST_TAINT_W;
> +       }
> +
> +       if ((taint & taint_mask) != 0)
>                 tst_brk(TBROK, "Kernel is already tainted: %u", taint);
>  }

> Other tests rely on TAINT_W to decide the result also report TPASS by
> misstake if TAINT_W was already set.
> In my patch v1 about CVE-2023-31248 check error == ENOENT. In this
> case, test reports correct result.
> It may be difficult to implement test like patch v1 using the internal
> tst_netlink API, but we should be aware of this issue.

Cc Jan. But if I read it correctly if the kernel is already tainted with
TAINT_W, this flag is indeed skipped, but it can still be detected via
TST_TAINT_D (oops).

Kind regards,
Petr


> Best regards.
> Souta Kawahara <souta.kawahara@miraclelinux.com>



> > Otherwise the patchset looks ok.

> > Kind regards,
> > Petr

> > --
> > Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-15  8:23       ` Petr Vorel
@ 2023-11-15  9:16         ` Jan Stancek
  0 siblings, 0 replies; 13+ messages in thread
From: Jan Stancek @ 2023-11-15  9:16 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

On Wed, Nov 15, 2023 at 9:23 AM Petr Vorel <pvorel@suse.cz> wrote:
>
> > Hi Martin, Petr.
>
>
> > 2023年11月15日(水) 0:39 Petr Vorel <pvorel@suse.cz>:
>
> > > Hi Martin,
>
> > > ...
> > > > +++ b/testcases/network/iptables/nft02.c
> > > ...
> > > > +/* Chain creation and deletion config */
> > > > +static const struct tst_netlink_attr_list newchain_config[] = {
> > > > +     {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
> > > > +     {NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
> > > > +     {NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
>
> > > Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
> > > for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?
>
> > It was the same on RHEL8 (and/or other clone OS).
>
> > And, I would like to see this test added to runtest/cve and .gitignore.
>
> Good point, thanks. Maybe it could be also in runtest/net.tcp_cmds.
>
> > > +       if (tst_taint_check()) {
> > > +               tst_res(TFAIL, "Kernel is vulnerable");
> > > +               return;
> > > +       }
>
> > Not a problem with the test itself but, If TAINT_W was already set,
> > the test report TPASS by misstake.
> > Below patch masks TAINT_W if that taint flag was set before test started.
>
> > commit de9b5c2636204ab06dbb3c7dc57296d73ac572ac
> > Author: Jan Stancek <jstancek@redhat.com>
> > Date:   Tue Apr 21 14:15:48 2020 +0200
>
> >     lib: tst_taint: Ignore WARN taint flag if already set
>
> >     This commit changes the library so that it ignores the taint warn flag
> >     if it was set prior to the test run. It turns out that the warn taint
> >     flag is not well defined and could be easily set on a freshly booted
> >     kernel for example when buggy BIOS is detected.
>
> >     Other recent example is disabling ip forward on kvm guests:
> >       https://github.com/containers/libpod/issues/5815
> >       https://lore.kernel.org/netdev/a47b6a3b-c064-2f53-7cf6-d0d0720e9d99@redhat.com/
>
> >     Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> >     Signed-off-by: Jan Stancek <jstancek@redhat.com>
> >     Cc: Chang Yin <cyin@redhat.com>
> >     Reviewed-by: Li Wang <liwang@redhat.com>
>
> > diff --git a/lib/tst_taint.c b/lib/tst_taint.c
> > index a5dbf77d2..49146aacb 100644
> > --- a/lib/tst_taint.c
> > +++ b/lib/tst_taint.c
> > @@ -82,9 +82,14 @@ void tst_taint_init(unsigned int mask)
> >                 tst_res(TCONF, "Kernel is too old for requested mask");
>
> >         taint_mask = mask;
> > -
> >         taint = tst_taint_read();
> > -       if ((taint & mask) != 0)
> > +
> > +       if (taint & TST_TAINT_W) {
> > +               tst_res(TCONF, "Ignoring already set kernel warning taint");
> > +               taint_mask &= ~TST_TAINT_W;
> > +       }
> > +
> > +       if ((taint & taint_mask) != 0)
> >                 tst_brk(TBROK, "Kernel is already tainted: %u", taint);
> >  }
>
> > Other tests rely on TAINT_W to decide the result also report TPASS by
> > misstake if TAINT_W was already set.
> > In my patch v1 about CVE-2023-31248 check error == ENOENT. In this
> > case, test reports correct result.
> > It may be difficult to implement test like patch v1 using the internal
> > tst_netlink API, but we should be aware of this issue.
>
> Cc Jan. But if I read it correctly if the kernel is already tainted with
> TAINT_W, this flag is indeed skipped, but it can still be detected via
> TST_TAINT_D (oops).

If we mask already set TAINT_W, you can get PASS by mistake,
if we don't mask it, you can get FAIL by mistake - which one is better?

I believe at the time we saw masking as better alternative, since many
CI systems also look at dmesg/journal and would find WARNING messages
even when test reports PASS by mistake. So the failure wouldn't go unnoticed.


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-15  7:43     ` 河原颯太
  2023-11-15  8:23       ` Petr Vorel
@ 2023-11-15 17:34       ` Martin Doucha
  2023-11-15 23:39         ` 河原颯太
  1 sibling, 1 reply; 13+ messages in thread
From: Martin Doucha @ 2023-11-15 17:34 UTC (permalink / raw)
  To: 河原颯太, Petr Vorel; +Cc: ltp

Hi,

On 15. 11. 23 8:43, 河原颯太 wrote:
> Hi Martin, Petr.
> 
> 
> 2023年11月15日(水) 0:39 Petr Vorel <pvorel@suse.cz>:
>>
>> Hi Martin,
>>
>> ...
>>> +++ b/testcases/network/iptables/nft02.c
>> ...
>>> +/* Chain creation and deletion config */
>>> +static const struct tst_netlink_attr_list newchain_config[] = {
>>> +     {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
>>> +     {NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
>>> +     {NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
>>
>> Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
>> for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?
> 
> It was the same on RHEL8 (and/or other clone OS).
> 
> And, I would like to see this test added to runtest/cve and .gitignore.

Yes, sorry, I realized that shortly after submission and will fix it in 
the next version.

> In my patch v1 about CVE-2023-31248 check error == ENOENT. In this
> case, test reports correct result.
> It may be difficult to implement test like patch v1 using the internal
> tst_netlink API, but we should be aware of this issue.

I've rewritten the test to use ENOENT check with the tst_netlink API. 
May I credit you with Co-Developed-by or Suggested-by (choose one)?

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248
  2023-11-15 17:34       ` Martin Doucha
@ 2023-11-15 23:39         ` 河原颯太
  0 siblings, 0 replies; 13+ messages in thread
From: 河原颯太 @ 2023-11-15 23:39 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

2023年11月16日(木) 2:34 Martin Doucha <mdoucha@suse.cz>:
>
> Hi,
>
> On 15. 11. 23 8:43, 河原颯太 wrote:
> > Hi Martin, Petr.
> >
> >
> > 2023年11月15日(水) 0:39 Petr Vorel <pvorel@suse.cz>:
> >>
> >> Hi Martin,
> >>
> >> ...
> >>> +++ b/testcases/network/iptables/nft02.c
> >> ...
> >>> +/* Chain creation and deletion config */
> >>> +static const struct tst_netlink_attr_list newchain_config[] = {
> >>> +     {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
> >>> +     {NFTA_CHAIN_NAME, CHAINNAME, strlen(CHAINNAME) + 1, NULL},
> >>> +     {NFTA_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
> >>
> >> Unfortunately the current oldest distros (Leap 42 and Ubuntu Bionic) are too old
> >> for NFTA_CHAIN_ID, NFTA_RULE_CHAIN_ID, could you please add them to LAPI?
> >
> > It was the same on RHEL8 (and/or other clone OS).
> >
> > And, I would like to see this test added to runtest/cve and .gitignore.
>
> Yes, sorry, I realized that shortly after submission and will fix it in
> the next version.
>
> > In my patch v1 about CVE-2023-31248 check error == ENOENT. In this
> > case, test reports correct result.
> > It may be difficult to implement test like patch v1 using the internal
> > tst_netlink API, but we should be aware of this issue.
>
> I've rewritten the test to use ENOENT check with the tst_netlink API.
> May I credit you with Co-Developed-by or Suggested-by (choose one)?

Good! Thank You so much.
Co-Developed-by is better for me :)

Best regards,
Souta Kawahara <souta.kawahara@miraclelinux.com>


>
> --
> Martin Doucha   mdoucha@suse.cz
> SW Quality Engineer
> SUSE LINUX, s.r.o.
> CORSO IIa
> Krizikova 148/34
> 186 00 Prague 8
> Czech Republic
>

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2023-11-15 23:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-14 12:31 [LTP] [PATCH v2 0/5] Netlink helper functions refactoring + CVE 2023-31248 Martin Doucha
2023-11-14 12:31 ` [LTP] [PATCH v2 1/5] tst_rtnetlink: Refactor helper function for generic use Martin Doucha
2023-11-14 19:14   ` Petr Vorel
2023-11-14 12:31 ` [LTP] [PATCH v2 2/5] tst_netlink_destroy_context(): Allow safely passing NULL context Martin Doucha
2023-11-14 12:31 ` [LTP] [PATCH v2 3/5] crypto: Replace old netlink helper functions with netlink contexts Martin Doucha
2023-11-14 12:31 ` [LTP] [PATCH v2 4/5] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
2023-11-14 12:31 ` [LTP] [PATCH v2 5/5] Add test for CVE 2023-31248 Martin Doucha
2023-11-14 15:39   ` Petr Vorel
2023-11-15  7:43     ` 河原颯太
2023-11-15  8:23       ` Petr Vorel
2023-11-15  9:16         ` Jan Stancek
2023-11-15 17:34       ` Martin Doucha
2023-11-15 23:39         ` 河原颯太

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox