[PATCH v2] Implement decoding of setsockopt(TCP_AO_ADD_KEY)
наб
nabijaczleweli at nabijaczleweli.xyz
Sun Mar 10 13:22:05 UTC 2024
Samples as run via tcp-ao-wrapper:
setsockopt(3, SOL_TCP, TCP_AO_ADD_KEY, {addr={sa_family=AF_INET6, sin6_port=htons(0), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::", &sin6_addr), sin6_scope_id=0}, prefix=0, alg_name="hmac(sha1)", ifindex=0, set_current=0, set_rnext=0, sndid=200, rcvid=100, maclen=12, keyflags=0, key="\x42\xe9\xd2\xd3\xd1\xec\x9f\x55\x56\x9c\xd7\x89\x1a\x90\x53\xba\x59\x6d\x5f\x0a", keylen=20}, 288) = 0
setsockopt(3, SOL_TCP, TCP_AO_ADD_KEY, {addr={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, prefix=32, alg_name="cmac(aes)", ifindex=0, set_current=0, set_rnext=0, sndid=200, rcvid=100, maclen=12, keyflags=0, key="\x7a\x66\x25\xc9\x80\xdb\x68\x95\xf5\xaf\x84\x1b\xd6\x50\x29\xe1", keylen=16}, 288) = -1 ENOPROTOOPT (Protocol not available)
---
keylen included;
I must've somehow missed PRINT_FIELD_U_CAST() yesterday,
that's perfect for the two bitfields.
NEWS | 1 +
src/net.c | 57 ++++++++++++++++++-
src/xlat/tcp_ao_keyf_flags.in | 3 +
tests/.gitignore | 1 +
tests/gen_tests.in | 1 +
tests/pure_executables.list | 1 +
tests/tcp_ao.c | 101 ++++++++++++++++++++++++++++++++++
7 files changed, 162 insertions(+), 3 deletions(-)
create mode 100644 src/xlat/tcp_ao_keyf_flags.in
create mode 100644 tests/tcp_ao.c
diff --git a/NEWS b/NEWS
index 8613cbc..d05e68d 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Noteworthy changes in release ?.? (????-??-??)
* Updated lists of BPF_*, KEXEC_*, KVM_*, PERF_*, SOL_*, STATX_*, UFFD_*,
and V4L2_* constants.
* Updated lists of ioctl commands from Linux 6.8.
+ * Implemented decoding of setsockopt(TCP_AO_ADD_KEY).
Noteworthy changes in release 6.7 (2024-01-29)
==============================================
diff --git a/src/net.c b/src/net.c
index e8878c4..9a18c11 100644
--- a/src/net.c
+++ b/src/net.c
@@ -16,9 +16,6 @@
#include <sys/uio.h>
#include <sys/un.h>
#include <netinet/in.h>
-#ifdef HAVE_NETINET_TCP_H
-# include <netinet/tcp.h>
-#endif
#ifdef HAVE_NETINET_UDP_H
# include <netinet/udp.h>
#endif
@@ -45,6 +42,7 @@
#endif
#include <linux/if_packet.h>
#include <linux/icmp.h>
+#include <linux/tcp.h>
#include <linux/vm_sockets.h>
#include "xlat/socktypes.h"
@@ -879,6 +877,51 @@ print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len)
tprint_bitset_end();
}
+#include "xlat/tcp_ao_keyf_flags.h"
+
+static void
+print_tcp_ao_add_key(struct tcb *const tcp, const kernel_ulong_t addr, int len)
+{
+ struct tcp_ao_add key = {};
+
+ if (len > (int) sizeof(key))
+ len = sizeof(key);
+ else if (len <= 0) {
+ printaddr(addr);
+ return;
+ }
+
+ if (umoven_or_printaddr(tcp, addr, len, &key))
+ return;
+
+ tprint_struct_begin();
+ PRINT_FIELD_SOCKADDR(key, addr, tcp);
+ tprint_struct_next();
+ PRINT_FIELD_U(key, prefix);
+ tprint_struct_next();
+ PRINT_FIELD_CSTRING(key, alg_name);
+ tprint_struct_next();
+ PRINT_FIELD_IFINDEX(key, ifindex);
+ tprint_struct_next();
+ PRINT_FIELD_U_CAST(key, set_current, unsigned);
+ tprint_struct_next();
+ PRINT_FIELD_U_CAST(key, set_rnext, unsigned);
+ tprint_struct_next();
+ PRINT_FIELD_U(key, sndid);
+ tprint_struct_next();
+ PRINT_FIELD_U(key, rcvid);
+ tprint_struct_next();
+ PRINT_FIELD_U(key, maclen);
+ tprint_struct_next();
+ PRINT_FIELD_FLAGS(key, keyflags, tcp_ao_keyf_flags, "TCP_AO_KEYF_???");
+ tprint_struct_next();
+ PRINT_FIELD_HEX_ARRAY_UPTO(key, key,
+ key.keylen > sizeof(key.key) ? sizeof(key.key) : key.keylen);
+ tprint_struct_next();
+ PRINT_FIELD_U(key, keylen);
+ tprint_struct_end();
+}
+
static void
print_getsockopt(struct tcb *const tcp, const unsigned int level,
const unsigned int name, const kernel_ulong_t addr,
@@ -1332,6 +1375,14 @@ print_setsockopt(struct tcb *const tcp, const unsigned int level,
else
printnum_int(tcp, addr, "%d");
return;
+
+ case SOL_TCP:
+ switch (name) {
+ case TCP_AO_ADD_KEY:
+ print_tcp_ao_add_key(tcp, addr, len);
+ return;
+ }
+ break;
}
/* default arg printing */
diff --git a/src/xlat/tcp_ao_keyf_flags.in b/src/xlat/tcp_ao_keyf_flags.in
new file mode 100644
index 0000000..caf6e2d
--- /dev/null
+++ b/src/xlat/tcp_ao_keyf_flags.in
@@ -0,0 +1,3 @@
+#unconditional
+TCP_AO_KEYF_IFINDEX
+TCP_AO_KEYF_EXCLUDE_OPT
diff --git a/tests/.gitignore b/tests/.gitignore
index 493714b..1aa7880 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1109,6 +1109,7 @@ sysinfo
syslog
syslog-success
tampering-notes
+tcp_ao
tee
tgkill
tgkill--pidns-translation
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 3499785..cdd25ec 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -1107,6 +1107,7 @@ sync_file_range2
sysctl -a16 --trace=_sysctl
sysinfo -a14
syslog -a35
+tcp_ao -e trace=getsockopt,setsockopt
tee
tgkill -a15 --signal='!cont'
tgkill--pidns-translation test_pidns -a15 --signal='!cont' -e trace=tgkill
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index b4af3cf..84cd766 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -794,6 +794,7 @@ sysctl
sysinfo
syslog
tampering-notes
+tcp_ao
tee
tgkill
time
diff --git a/tests/tcp_ao.c b/tests/tcp_ao.c
new file mode 100644
index 0000000..df079bc
--- /dev/null
+++ b/tests/tcp_ao.c
@@ -0,0 +1,101 @@
+/*
+ * Check decoding of SO_LINGER socket option.
+ *
+ * Copyright (c) 2017-2021 Dmitry V. Levin <ldv at strace.io>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <linux/tcp.h>
+#include <netinet/in.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+static const char *errstr;
+
+static int
+add_key(int fd, struct tcp_ao_add *val)
+{
+ int rc = setsockopt(fd, IPPROTO_TCP, TCP_AO_ADD_KEY, val, sizeof(*val));
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct tcp_ao_add, key);
+
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ perror_msg_and_skip("socket AF_TCP SOCK_STREAM");
+
+
+#define KEY1 "\x42\xe9\xd2\xd3\xd1\xec\x9f\x55\x56\x9c\xd7\x89\x1a\x90\x53\xba\x59\x6d\x5f\x0a"
+ *key = (struct tcp_ao_add){
+ .prefix = 0,
+ .alg_name = "hmac(sha1)",
+ .ifindex = 0,
+ .set_current = 0,
+ .set_rnext = 0,
+ .sndid = 200,
+ .rcvid = 100,
+ .maclen = 12,
+ .keyflags = 0,
+ .key = KEY1,
+ .keylen = sizeof(KEY1) - 1,
+ };
+ struct sockaddr_in6 addr6 =
+ {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT};
+ memcpy(&key->addr, &addr6, sizeof(addr6));
+ add_key(fd, key);
+ printf("setsockopt(%d, SOL_TCP, TCP_AO_ADD_KEY, "
+ "{addr={sa_family=AF_INET6, sin6_port=htons(0), "
+ "sin6_flowinfo=htonl(0), inet_pton(AF_INET6, \"::\", "
+ "&sin6_addr), sin6_scope_id=0}, prefix=0, "
+ "alg_name=\"hmac(sha1)\", ifindex=0, set_current=0, "
+ "set_rnext=0, sndid=200, rcvid=100, maclen=12, keyflags=0, "
+ "key="
+ "\"\\x42\\xe9\\xd2\\xd3\\xd1\\xec\\x9f\\x55\\x56\\x9c\\xd7\\x89"
+ "\\x1a\\x90\\x53\\xba\\x59\\x6d\\x5f\\x0a\", keylen=%zu}"
+ ", %zu) = %s\n",
+ fd, sizeof(KEY1) - 1, sizeof(*key), errstr);
+
+#define KEY2 "\x7a\x66\x25\xc9\x80\xdb\x68\x95\xf5\xaf\x84\x1b\xd6\x50\x29\xe1"
+ *key = (struct tcp_ao_add){
+ .prefix = 32,
+ .alg_name = "cmac(aes)",
+ .ifindex = 0,
+ .set_current = 0,
+ .set_rnext = 0,
+ .sndid = 200,
+ .rcvid = 100,
+ .maclen = 12,
+ .keyflags = TCP_AO_KEYF_IFINDEX|TCP_AO_KEYF_EXCLUDE_OPT,
+ .key = KEY2,
+ .keylen = sizeof(KEY2) - 1,
+ };
+ struct sockaddr_in addr =
+ {.sin_family = AF_INET, .sin_addr = {htonl(INADDR_LOOPBACK)}};
+ memcpy(&key->addr, &addr, sizeof(addr));
+ add_key(fd, key);
+ printf("setsockopt(%d, SOL_TCP, TCP_AO_ADD_KEY, "
+ "{addr={sa_family=AF_INET, sin_port=htons(0), "
+ "sin_addr=inet_addr(\"127.0.0.1\")}, prefix=32, "
+ "alg_name=\"cmac(aes)\", ifindex=0, set_current=0, set_rnext=0, "
+ "sndid=200, rcvid=100, maclen=12, "
+ "keyflags=TCP_AO_KEYF_IFINDEX|TCP_AO_KEYF_EXCLUDE_OPT, key="
+ "\"\\x7a\\x66\\x25\\xc9\\x80\\xdb\\x68\\x95\\xf5\\xaf\\x84\\x1b"
+ "\\xd6\\x50\\x29\\xe1\", keylen=%zu}"
+ ", %zu) = %s\n",
+ fd, sizeof(KEY2) - 1, sizeof(*key), errstr);
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
--
2.39.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20240310/1c1c9348/attachment.bin>
More information about the Strace-devel
mailing list