* [LTP] [PATCH v4 0/4] Test for CVE 2023-31248
@ 2023-11-21 15:42 Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 1/4] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Martin Doucha @ 2023-11-21 15:42 UTC (permalink / raw)
To: ltp
Add test for CVE 2023-31248. Support for older kernels requires some
changes in tst_netlink_check_acks() and a new LAPI header.
Changes tested on kernels 4.4, 4.12 and 5.14.
Martin Doucha (4):
tst_netlink: Add helper functions for handling generic attributes
tst_netlink_check_acks(): Stop on first error regardless of ACK
request
Add lapi/nf_tables.h
Add test for CVE 2023-31248
configure.ac | 1 +
doc/C-Test-Network-API.asciidoc | 66 +++++---
include/lapi/nf_tables.h | 19 +++
include/tst_netdevice.h | 6 +-
include/tst_netlink.h | 38 ++++-
lib/tst_netdevice.c | 20 +--
lib/tst_netlink.c | 97 +++++++++++-
runtest/cve | 1 +
testcases/cve/tcindex01.c | 12 +-
testcases/network/iptables/.gitignore | 1 +
testcases/network/iptables/Makefile | 2 +-
testcases/network/iptables/nft02.c | 216 ++++++++++++++++++++++++++
12 files changed, 423 insertions(+), 56 deletions(-)
create mode 100644 include/lapi/nf_tables.h
create mode 100644 testcases/network/iptables/.gitignore
create mode 100644 testcases/network/iptables/nft02.c
--
2.42.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [PATCH v4 1/4] tst_netlink: Add helper functions for handling generic attributes
2023-11-21 15:42 [LTP] [PATCH v4 0/4] Test for CVE 2023-31248 Martin Doucha
@ 2023-11-21 15:42 ` Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 2/4] tst_netlink_check_acks(): Stop on first error regardless of ACK request Martin Doucha
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Martin Doucha @ 2023-11-21 15:42 UTC (permalink / raw)
To: 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>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
Changes since v1: New patch
Changes since v2: None
Changes since v3: Updated docs
NETLINK_ADD_ATTR_STRING() is currently unused but it was added for future use.
doc/C-Test-Network-API.asciidoc | 66 +++++++++++++++++---------
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 ++---
6 files changed, 176 insertions(+), 48 deletions(-)
diff --git a/doc/C-Test-Network-API.asciidoc b/doc/C-Test-Network-API.asciidoc
index 6145e6718..feedd5a95 100644
--- a/doc/C-Test-Network-API.asciidoc
+++ b/doc/C-Test-Network-API.asciidoc
@@ -293,11 +293,11 @@ stage.
-------------------------------------------------------------------------------
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 {
@@ -313,12 +313,13 @@ constructing and sending arbitrary messages using the functions described
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
++struct tst_netlink_attr_list+ is a helper structure for defining complex
rtnetlink message attribute payloads, including nested attribute lists. Every
list and sublist defined using this structure is terminated by item with
negative +len+.
-- +type+ is the attribute type that will be stored in +struct rtattr.rta_type+.
+- +type+ is the attribute type that will be stored in +struct nlattr.nla_type+
+ or +struct rtattr.rta_type+.
- +data+ contains arbitrary attribute payload.
@@ -326,10 +327,10 @@ negative +len+.
set +len+ to 0. The last item in a list or sublist must have negative length.
- +sublist+ contains a nested attribute list which will be appended after
- +data+ as part of the attribute payload. +struct rtattr.rta_len+ will be
- calculated automatically with proper alignment, do _not_ add the sublist size
- to the +len+ field. If you do not want to add nested attributes, set
- +sublist+ to +NULL+.
+ +data+ as part of the attribute payload. +struct nlattr.nla_len+ or
+ +struct rtattr.rta_len+ will be calculated automatically with proper
+ alignment, do _not_ add the sublist size to the +len+ field. If you do not
+ want to add nested attributes, set +sublist+ to +NULL+.
+struct tst_netlink_message+ is a structure holding partially parsed netlink
messages received from the kernel. +NETLINK_RECV()+ returns an array of these
@@ -412,24 +413,47 @@ structures with the last item having +NULL+ in the +header+ field. Call
and +NETLINK_CHECK_ACKS()+ will not work correctly until the next
+NETLINK_SEND()+.
+- +int NETLINK_ADD_ATTR(struct tst_netlink_context *ctx, unsigned short type,
+ const void *data, unsigned short len)+ – Adds new +struct nlattr+ attribute
+ to the last message in +ctx+ buffer. See +NETLINK_ADD_MESSAGE()+. You need
+ to provide attribute +type+ which will be stored in +struct nlattr.nla_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 NETLINK_ADD_ATTR_STRING(struct tst_netlink_context *ctx, unsigned short
+ type, const char *data)+ – Adds new +struct nlattr+ string attribute to the
+ last message in +ctx+ buffer. Parameters and return value are the same as
+ for +NETLINK_ADD_ATTR()+, except the payload length is calculated using
+ +strlen()+.
+
+- +int NETLINK_ADD_ATTR_LIST(struct tst_netlink_context *ctx, const struct
+ tst_netlink_attr_list *list)+ – Adds a list of +struct nlattr+ attributes
+ to the last message in +ctx+ buffer. See description of
+ +struct tst_netlink_attr_list+ and +NETLINK_ADD_MESSAGE()+ above. Returns
+ the number of added attributes on success (nested attributes are not
+ counted), -1 on error.
+
- +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.
+ const void *data, unsigned short len)+ – Adds new +struct rtattr+ 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()+.
+ type, const char *data)+ – Adds new +struct rtattr+ 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
- +NETLINK_ADD_MESSAGE()+ above. Returns the number of added attributes on
- success (nested attributes are not counted), -1 on error.
+ tst_netlink_attr_list *list)+ – Adds a list of +struct rtattr+ attributes
+ to the last message in +ctx+ buffer. See description of
+ +struct tst_netlink_attr_list+ and +NETLINK_ADD_MESSAGE()+ above. Returns
+ the number of added attributes on success (nested attributes are not
+ counted), -1 on error.
Example Usage
+++++++++++++
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.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [LTP] [PATCH v4 2/4] tst_netlink_check_acks(): Stop on first error regardless of ACK request
2023-11-21 15:42 [LTP] [PATCH v4 0/4] Test for CVE 2023-31248 Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 1/4] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
@ 2023-11-21 15:42 ` Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 3/4] Add lapi/nf_tables.h Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248 Martin Doucha
3 siblings, 0 replies; 6+ messages in thread
From: Martin Doucha @ 2023-11-21 15:42 UTC (permalink / raw)
To: ltp
tst_netlink_check_acks() currently ignores errors in response
to netlink messages that did not explicitly ask for ack.
If a multimessage netlink request fails early, this will lead
to TBROK failures due to missing acks. Return the first netlink
error even if the corresponding request did not ask for ack.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
Changes since v2: New patch
lib/tst_netlink.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/lib/tst_netlink.c b/lib/tst_netlink.c
index 7bc98af56..d61cc8b88 100644
--- a/lib/tst_netlink.c
+++ b/lib/tst_netlink.c
@@ -455,18 +455,19 @@ int tst_netlink_check_acks(const char *file, const int lineno,
if (!(msg->nlmsg_flags & NLM_F_ACK))
continue;
- while (res->header && res->header->nlmsg_seq != msg->nlmsg_seq)
+ while (res->header && !(res->err && res->err->error) &&
+ res->header->nlmsg_seq != msg->nlmsg_seq)
res++;
- if (!res->err || res->header->nlmsg_seq != msg->nlmsg_seq) {
- tst_brk_(file, lineno, TBROK,
- "No ACK found for Netlink message %u",
- msg->nlmsg_seq);
+ if (res->err && res->err->error) {
+ tst_netlink_errno = -res->err->error;
return 0;
}
- if (res->err->error) {
- tst_netlink_errno = -res->err->error;
+ if (!res->header || res->header->nlmsg_seq != msg->nlmsg_seq) {
+ tst_brk_(file, lineno, TBROK,
+ "No ACK found for Netlink message %u",
+ msg->nlmsg_seq);
return 0;
}
}
--
2.42.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [LTP] [PATCH v4 3/4] Add lapi/nf_tables.h
2023-11-21 15:42 [LTP] [PATCH v4 0/4] Test for CVE 2023-31248 Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 1/4] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 2/4] tst_netlink_check_acks(): Stop on first error regardless of ACK request Martin Doucha
@ 2023-11-21 15:42 ` Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248 Martin Doucha
3 siblings, 0 replies; 6+ messages in thread
From: Martin Doucha @ 2023-11-21 15:42 UTC (permalink / raw)
To: ltp
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
Changes since v2: New patch
Changes since v3: Fixed copyright header
configure.ac | 1 +
include/lapi/nf_tables.h | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 include/lapi/nf_tables.h
diff --git a/configure.ac b/configure.ac
index 3fa350f9e..e1a10a10e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,7 @@ AC_PREFIX_DEFAULT(/opt/ltp)
AC_CHECK_DECLS([IFLA_NET_NS_PID],,,[#include <linux/if_link.h>])
AC_CHECK_DECLS([MADV_MERGEABLE],,,[#include <sys/mman.h>])
+AC_CHECK_DECLS([NFTA_CHAIN_ID, NFTA_VERDICT_CHAIN_ID],,,[#include <linux/netfilter/nf_tables.h>])
AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ],,,[#include <sys/prctl.h>])
AC_CHECK_DECLS([SEM_STAT_ANY],,,[#include <sys/sem.h>])
diff --git a/include/lapi/nf_tables.h b/include/lapi/nf_tables.h
new file mode 100644
index 000000000..9feb3a60e
--- /dev/null
+++ b/include/lapi/nf_tables.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 SUSE LLC <mdoucha@suse.cz>
+ */
+
+#ifndef LAPI_NF_TABLES_H__
+#define LAPI_NF_TABLES_H__
+
+#include <linux/netfilter/nf_tables.h>
+
+#ifndef HAVE_DECL_NFTA_CHAIN_ID
+# define NFTA_CHAIN_ID 11
+#endif
+
+#ifndef HAVE_DECL_NFTA_VERDICT_CHAIN_ID
+# define NFTA_VERDICT_CHAIN_ID 3
+#endif
+
+#endif /* LAPI_NF_TABLES_H__ */
--
2.42.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248
2023-11-21 15:42 [LTP] [PATCH v4 0/4] Test for CVE 2023-31248 Martin Doucha
` (2 preceding siblings ...)
2023-11-21 15:42 ` [LTP] [PATCH v4 3/4] Add lapi/nf_tables.h Martin Doucha
@ 2023-11-21 15:42 ` Martin Doucha
2023-11-21 16:26 ` Petr Vorel
3 siblings, 1 reply; 6+ messages in thread
From: Martin Doucha @ 2023-11-21 15:42 UTC (permalink / raw)
To: ltp
Fixes #1058
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
Co-Developed-by: Souta Kawahara <souta.kawahara@miraclelinux.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Tested-by: Petr Vorel <pvorel@suse.cz>
---
Changes since v1: New patch
Changes since v2:
- Use netfilter GOTO rule jumping into the deleted chain
- Check for ENOENT error instead of kernel taint
Changes since v3: Code style and typo fixes
The test does not use any external utilities so I've decided not to add it
to the net.tcp_cmds runfile.
runtest/cve | 1 +
testcases/network/iptables/.gitignore | 1 +
testcases/network/iptables/Makefile | 2 +-
testcases/network/iptables/nft02.c | 216 ++++++++++++++++++++++++++
4 files changed, 219 insertions(+), 1 deletion(-)
create mode 100644 testcases/network/iptables/.gitignore
create mode 100644 testcases/network/iptables/nft02.c
diff --git a/runtest/cve b/runtest/cve
index 569558af2..1d1d87597 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -86,6 +86,7 @@ cve-2022-2590 dirtyc0w_shmem
cve-2022-23222 bpf_prog07
cve-2023-1829 tcindex01
cve-2023-0461 setsockopt10
+cve-2023-31248 nft02
# Tests below may cause kernel memory leak
cve-2020-25704 perf_event_open03
cve-2022-0185 fsconfig03
diff --git a/testcases/network/iptables/.gitignore b/testcases/network/iptables/.gitignore
new file mode 100644
index 000000000..0f47a7313
--- /dev/null
+++ b/testcases/network/iptables/.gitignore
@@ -0,0 +1 @@
+nft02
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..8b7248c69
--- /dev/null
+++ b/testcases/network/iptables/nft02.c
@@ -0,0 +1,216 @@
+// 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>
+ */
+
+/*\
+ * [Description]
+ *
+ * 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 "lapi/nf_tables.h"
+#include <linux/netfilter/nfnetlink.h>
+#include "tst_test.h"
+#include "tst_netlink.h"
+
+#define TABNAME "ltp_table1"
+#define SRCCHAIN "ltp_chain_src"
+#define DESTCHAIN "ltp_chain_dest"
+#define DESTCHAIN_ID 77
+
+static uint32_t chain_id;
+static uint32_t imm_dreg, imm_verdict;
+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 destchain_config[] = {
+ {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
+ {NFTA_CHAIN_NAME, DESTCHAIN, strlen(DESTCHAIN) + 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, DESTCHAIN, strlen(DESTCHAIN) + 1, NULL},
+ {0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list srcchain_config[] = {
+ {NFTA_TABLE_NAME, TABNAME, strlen(TABNAME) + 1, NULL},
+ {NFTA_CHAIN_NAME, SRCCHAIN, strlen(SRCCHAIN) + 1, NULL},
+ {0, NULL, -1, NULL}
+};
+
+/* Rule creation config */
+static const struct tst_netlink_attr_list rule_verdict_config[] = {
+ {NFTA_VERDICT_CODE, &imm_verdict, sizeof(imm_verdict), NULL},
+ {NFTA_VERDICT_CHAIN_ID, &chain_id, sizeof(chain_id), NULL},
+ {0, NULL, -1, NULL}
+};
+
+static const struct tst_netlink_attr_list rule_data_config[] = {
+ {NFTA_IMMEDIATE_DREG, &imm_dreg, sizeof(imm_dreg), NULL},
+ {NFTA_IMMEDIATE_DATA, NULL, 0, (const struct tst_netlink_attr_list[]) {
+ {NFTA_DATA_VERDICT, NULL, 0, rule_verdict_config},
+ {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, "immediate", 10, NULL},
+ {NFTA_EXPR_DATA, NULL, 0, rule_data_config},
+ {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, SRCCHAIN, strlen(SRCCHAIN) + 1, NULL},
+ {0, NULL, -1, NULL}
+};
+
+static void setup(void)
+{
+ tst_setup_netns();
+
+ chain_id = htonl(DESTCHAIN_ID);
+ imm_dreg = htonl(NFT_REG_VERDICT);
+ imm_verdict = htonl(NFT_GOTO);
+}
+
+static void run(void)
+{
+ int ret;
+ 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;
+ 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 destination chain */
+ header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWCHAIN;
+ header.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
+ nfpayload.nfgen_family = NFPROTO_IPV4;
+ nfpayload.res_id = htons(0);
+ NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+ NETLINK_ADD_ATTR_LIST(ctx, destchain_config);
+
+ /* Delete destination chain */
+ header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_DELCHAIN;
+ header.nlmsg_flags = NLM_F_REQUEST;
+ 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 source chain */
+ header.nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWCHAIN;
+ header.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
+ nfpayload.nfgen_family = NFPROTO_IPV4;
+ nfpayload.res_id = htons(0);
+ NETLINK_ADD_MESSAGE(ctx, &header, &nfpayload, sizeof(nfpayload));
+ NETLINK_ADD_ATTR_LIST(ctx, srcchain_config);
+
+ /* Add rule to source chain. Require ACK and check for ENOENT error. */
+ 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));
+
+ ret = NETLINK_SEND_VALIDATE(ctx);
+ TST_ERR = tst_netlink_errno;
+ NETLINK_DESTROY_CONTEXT(ctx);
+ ctx = NULL;
+
+ if (ret)
+ tst_res(TFAIL, "Netfilter chain list is corrupted");
+ else if (TST_ERR == ENOENT)
+ tst_res(TPASS, "Deleted netfilter chain cannot be referenced");
+ else if (TST_ERR == EOPNOTSUPP || TST_ERR == EINVAL)
+ tst_brk(TCONF, "Test requires unavailable netfilter features");
+ else
+ tst_brk(TBROK | TTERRNO, "Unknown nfnetlink error");
+}
+
+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.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248
2023-11-21 15:42 ` [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248 Martin Doucha
@ 2023-11-21 16:26 ` Petr Vorel
0 siblings, 0 replies; 6+ messages in thread
From: Petr Vorel @ 2023-11-21 16:26 UTC (permalink / raw)
To: Martin Doucha; +Cc: ltp
Hi Martin,
patchset merged, thank you!
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-11-21 16:26 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-21 15:42 [LTP] [PATCH v4 0/4] Test for CVE 2023-31248 Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 1/4] tst_netlink: Add helper functions for handling generic attributes Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 2/4] tst_netlink_check_acks(): Stop on first error regardless of ACK request Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 3/4] Add lapi/nf_tables.h Martin Doucha
2023-11-21 15:42 ` [LTP] [PATCH v4 4/4] Add test for CVE 2023-31248 Martin Doucha
2023-11-21 16:26 ` Petr Vorel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox