* [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 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