summaryrefslogtreecommitdiff
path: root/src/test/test-socket-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-11-30 11:54:42 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-11-30 21:58:47 +0100
commit15dca3711da63ac5fcfa01187a3b964d7042b99c (patch)
treecfa17baae1d3ff6d88e9b936ed67181536fdc9bb /src/test/test-socket-util.c
parent3a484991535187a1a301eb5df2053a88bc87e2fa (diff)
downloadsystemd-15dca3711da63ac5fcfa01187a3b964d7042b99c.tar.gz
basic/socket-util: use c-escaping to print unprintable socket paths
We are pretty careful to reject abstract sockets that are too long to fit in the address structure as a NUL-terminated string. And since we parse sockets as strings, it is not possible to embed a NUL in the the address either. But we might receive an external socket (abstract or not), and we want to be able to print its address in all cases. We would call socket_address_verify() and refuse to print various sockets that the kernel considers legit. Let's do the strict verification only in case of socket addresses we parse and open ourselves, and do less strict verification when printing addresses of existing sockets, and use c-escaping to print embedded NULs and such. More tests are added. This should make LGTM happier because on FIXME comment is removed.
Diffstat (limited to 'src/test/test-socket-util.c')
-rw-r--r--src/test/test-socket-util.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 687caf83be..349d866442 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -6,6 +6,7 @@
#include "alloc-util.h"
#include "async.h"
+#include "escape.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
@@ -62,6 +63,9 @@ static void test_socket_address_parse_one(const char *in, int ret, int family, c
}
}
+#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path))
+assert_cc(sizeof(((struct sockaddr_un){}).sun_path) == 108);
+
static void test_socket_address_parse(void) {
log_info("/* %s */", __func__);
@@ -95,8 +99,21 @@ static void test_socket_address_parse(void) {
test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
+ test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
+ {
+ char aaa[SUN_PATH_LEN + 1] = "@";
+
+ memset(aaa + 1, 'a', SUN_PATH_LEN - 1);
+ char_array_0(aaa);
+
+ test_socket_address_parse_one(aaa, -EINVAL, 0, NULL);
+
+ aaa[SUN_PATH_LEN - 1] = '\0';
+ test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL);
+ }
+
test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL);
test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL);
test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL);
@@ -104,6 +121,40 @@ static void test_socket_address_parse(void) {
test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL);
}
+static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) {
+ _cleanup_free_ char *out = NULL, *c = NULL;
+
+ SocketAddress a = { .sockaddr = { .un = { .sun_family = AF_UNIX } },
+ .size = offsetof(struct sockaddr_un, sun_path) + len_in,
+ .type = SOCK_STREAM,
+ };
+ memcpy(a.sockaddr.un.sun_path, in, len_in);
+
+ assert_se(socket_address_print(&a, &out) >= 0);
+ assert_se(c = cescape(in));
+ log_info("\"%s\" → \"%s\" (expect \"%s\")", in, out, expected);
+ assert_se(streq(out, expected));
+}
+
+static void test_socket_print_unix(void) {
+ log_info("/* %s */", __func__);
+
+ /* Some additional tests for abstract addresses which we don't parse */
+
+ test_socket_print_unix_one("\0\0\0\0", 4, "@\\000\\000\\000");
+ test_socket_print_unix_one("@abs", 5, "@abs");
+ test_socket_print_unix_one("\n", 2, "\\n");
+ test_socket_print_unix_one("", 1, "<unnamed>");
+ test_socket_print_unix_one("\0", 1, "<unnamed>");
+ test_socket_print_unix_one("\0_________________________there's 108 characters in this string_____________________________________________", 108,
+ "@_________________________there\\'s 108 characters in this string_____________________________________________");
+ test_socket_print_unix_one("////////////////////////////////////////////////////////////////////////////////////////////////////////////", 108,
+ "////////////////////////////////////////////////////////////////////////////////////////////////////////////");
+ test_socket_print_unix_one("////////////////////////////////////////////////////////////////////////////////////////////////////////////", 109,
+ "////////////////////////////////////////////////////////////////////////////////////////////////////////////");
+ test_socket_print_unix_one("\0\a\b\n\255", 6, "@\\a\\b\\n\\255\\000");
+}
+
static void test_socket_address_parse_netlink(void) {
SocketAddress a;
@@ -748,6 +799,7 @@ int main(int argc, char *argv[]) {
test_ifname_valid();
test_socket_address_parse();
+ test_socket_print_unix();
test_socket_address_parse_netlink();
test_socket_address_equal();
test_socket_address_get_path();