LCOV - code coverage report
Current view: top level - test - test-socket-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 485 551 88.0 %
Date: 2019-08-23 13:36:53 Functions: 31 31 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 260 570 45.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <fcntl.h>
       4                 :            : #include <grp.h>
       5                 :            : #include <sys/stat.h>
       6                 :            : #include <sys/types.h>
       7                 :            : #include <unistd.h>
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "async.h"
      11                 :            : #include "escape.h"
      12                 :            : #include "exit-status.h"
      13                 :            : #include "fd-util.h"
      14                 :            : #include "in-addr-util.h"
      15                 :            : #include "io-util.h"
      16                 :            : #include "log.h"
      17                 :            : #include "macro.h"
      18                 :            : #include "missing_network.h"
      19                 :            : #include "process-util.h"
      20                 :            : #include "socket-util.h"
      21                 :            : #include "string-util.h"
      22                 :            : #include "tests.h"
      23                 :            : #include "tmpfile-util.h"
      24                 :            : 
      25                 :          4 : static void test_ifname_valid(void) {
      26         [ +  - ]:          4 :         log_info("/* %s */", __func__);
      27                 :            : 
      28         [ -  + ]:          4 :         assert(ifname_valid("foo"));
      29         [ -  + ]:          4 :         assert(ifname_valid("eth0"));
      30                 :            : 
      31         [ -  + ]:          4 :         assert(!ifname_valid("0"));
      32         [ -  + ]:          4 :         assert(!ifname_valid("99"));
      33         [ -  + ]:          4 :         assert(ifname_valid("a99"));
      34         [ -  + ]:          4 :         assert(ifname_valid("99a"));
      35                 :            : 
      36         [ -  + ]:          4 :         assert(!ifname_valid(NULL));
      37         [ -  + ]:          4 :         assert(!ifname_valid(""));
      38         [ -  + ]:          4 :         assert(!ifname_valid(" "));
      39         [ -  + ]:          4 :         assert(!ifname_valid(" foo"));
      40         [ -  + ]:          4 :         assert(!ifname_valid("bar\n"));
      41         [ -  + ]:          4 :         assert(!ifname_valid("."));
      42         [ -  + ]:          4 :         assert(!ifname_valid(".."));
      43         [ -  + ]:          4 :         assert(ifname_valid("foo.bar"));
      44         [ -  + ]:          4 :         assert(!ifname_valid("x:y"));
      45                 :            : 
      46         [ -  + ]:          4 :         assert(ifname_valid("xxxxxxxxxxxxxxx"));
      47         [ -  + ]:          4 :         assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
      48                 :          4 : }
      49                 :            : 
      50                 :        116 : static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {
      51                 :            :         SocketAddress a;
      52                 :        116 :         _cleanup_free_ char *out = NULL;
      53                 :            :         int r;
      54                 :            : 
      55                 :        116 :         r = socket_address_parse(&a, in);
      56         [ +  + ]:        116 :         if (r >= 0)
      57         [ -  + ]:         44 :                 assert_se(socket_address_print(&a, &out) >= 0);
      58                 :            : 
      59   [ +  -  +  +  :        116 :         log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in,
             +  +  +  + ]
      60                 :            :                  r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-");
      61         [ -  + ]:        116 :         assert_se(r == ret);
      62         [ +  + ]:        116 :         if (r >= 0) {
      63         [ -  + ]:         44 :                 assert_se(a.sockaddr.sa.sa_family == family);
      64   [ +  +  -  + ]:         44 :                 assert_se(streq(out, expected ?: in));
      65                 :            :         }
      66                 :        116 : }
      67                 :            : 
      68                 :            : #define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path))
      69                 :            : assert_cc(sizeof(((struct sockaddr_un){}).sun_path) == 108);
      70                 :            : 
      71                 :          4 : static void test_socket_address_parse(void) {
      72         [ +  - ]:          4 :         log_info("/* %s */", __func__);
      73                 :            : 
      74                 :          4 :         test_socket_address_parse_one("junk", -EINVAL, 0, NULL);
      75                 :          4 :         test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL);
      76                 :          4 :         test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL);
      77                 :          4 :         test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL);
      78                 :          4 :         test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL);
      79                 :          4 :         test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL);
      80                 :          4 :         test_socket_address_parse_one("0", -EINVAL, 0, NULL);
      81                 :          4 :         test_socket_address_parse_one("65536", -ERANGE, 0, NULL);
      82                 :            : 
      83         [ +  - ]:          4 :         const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET;
      84                 :            : 
      85                 :          4 :         test_socket_address_parse_one("65535", 0, default_family, "[::]:65535");
      86                 :            : 
      87                 :            :         /* The checks below will pass even if ipv6 is disabled in
      88                 :            :          * kernel. The underlying glibc's inet_pton() is just a string
      89                 :            :          * parser and doesn't make any syscalls. */
      90                 :            : 
      91                 :          4 :         test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL);
      92                 :          4 :         test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL);
      93                 :          4 :         test_socket_address_parse_one("::1", -EINVAL, 0, NULL);
      94                 :          4 :         test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
      95                 :          4 :         test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
      96                 :          4 :         test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
      97                 :            : 
      98                 :          4 :         test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
      99                 :          4 :         test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
     100                 :            :                                       "[2001:db8:0:85a3::ac1f:8001]:8888");
     101                 :          4 :         test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
     102                 :          4 :         test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
     103                 :          4 :         test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
     104                 :          4 :         test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
     105                 :          4 :         test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
     106                 :            : 
     107                 :            :         {
     108                 :          4 :                 char aaa[SUN_PATH_LEN + 1] = "@";
     109                 :            : 
     110                 :          4 :                 memset(aaa + 1, 'a', SUN_PATH_LEN - 1);
     111                 :          4 :                 char_array_0(aaa);
     112                 :            : 
     113                 :          4 :                 test_socket_address_parse_one(aaa, -EINVAL, 0, NULL);
     114                 :            : 
     115                 :          4 :                 aaa[SUN_PATH_LEN - 1] = '\0';
     116                 :          4 :                 test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL);
     117                 :            :         }
     118                 :            : 
     119                 :          4 :         test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL);
     120                 :          4 :         test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL);
     121                 :          4 :         test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL);
     122                 :          4 :         test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL);
     123                 :          4 :         test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL);
     124                 :          4 : }
     125                 :            : 
     126                 :         36 : static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) {
     127                 :         36 :         _cleanup_free_ char *out = NULL, *c = NULL;
     128                 :            : 
     129                 :         72 :         SocketAddress a = { .sockaddr = { .un = { .sun_family = AF_UNIX } },
     130                 :         36 :                             .size = offsetof(struct sockaddr_un, sun_path) + len_in,
     131                 :            :                             .type = SOCK_STREAM,
     132                 :            :         };
     133                 :         36 :         memcpy(a.sockaddr.un.sun_path, in, len_in);
     134                 :            : 
     135         [ -  + ]:         36 :         assert_se(socket_address_print(&a, &out) >= 0);
     136         [ -  + ]:         36 :         assert_se(c = cescape(in));
     137         [ +  - ]:         36 :         log_info("\"%s\" → \"%s\" (expect \"%s\")", in, out, expected);
     138         [ -  + ]:         36 :         assert_se(streq(out, expected));
     139                 :         36 : }
     140                 :            : 
     141                 :          4 : static void test_socket_print_unix(void) {
     142         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     143                 :            : 
     144                 :            :         /* Some additional tests for abstract addresses which we don't parse */
     145                 :            : 
     146                 :          4 :         test_socket_print_unix_one("\0\0\0\0", 4, "@\\000\\000\\000");
     147                 :          4 :         test_socket_print_unix_one("@abs", 5, "@abs");
     148                 :          4 :         test_socket_print_unix_one("\n", 2, "\\n");
     149                 :          4 :         test_socket_print_unix_one("", 1, "<unnamed>");
     150                 :          4 :         test_socket_print_unix_one("\0", 1, "<unnamed>");
     151                 :          4 :         test_socket_print_unix_one("\0_________________________there's 108 characters in this string_____________________________________________", 108,
     152                 :            :                                    "@_________________________there\\'s 108 characters in this string_____________________________________________");
     153                 :          4 :         test_socket_print_unix_one("////////////////////////////////////////////////////////////////////////////////////////////////////////////", 108,
     154                 :            :                                    "////////////////////////////////////////////////////////////////////////////////////////////////////////////");
     155                 :          4 :         test_socket_print_unix_one("////////////////////////////////////////////////////////////////////////////////////////////////////////////", 109,
     156                 :            :                                    "////////////////////////////////////////////////////////////////////////////////////////////////////////////");
     157                 :          4 :         test_socket_print_unix_one("\0\a\b\n\255", 6, "@\\a\\b\\n\\255\\000");
     158                 :          4 : }
     159                 :            : 
     160                 :          4 : static void test_socket_address_parse_netlink(void) {
     161                 :            :         SocketAddress a;
     162                 :            : 
     163         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     164                 :            : 
     165         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "junk") < 0);
     166         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "") < 0);
     167                 :            : 
     168         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "route") >= 0);
     169         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
     170         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_groups == 0);
     171         [ -  + ]:          4 :         assert_se(a.protocol == NETLINK_ROUTE);
     172         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "route") >= 0);
     173         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
     174         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
     175         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_groups == 10);
     176         [ -  + ]:          4 :         assert_se(a.protocol == NETLINK_ROUTE);
     177                 :            : 
     178                 :            :         /* With spaces and tabs */
     179         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0);
     180         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
     181         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_groups == 0);
     182         [ -  + ]:          4 :         assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
     183         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0);
     184         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
     185         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_groups == 10);
     186         [ -  + ]:          4 :         assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
     187         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0);
     188         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
     189         [ -  + ]:          4 :         assert_se(a.sockaddr.nl.nl_groups == 10);
     190         [ -  + ]:          4 :         assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
     191                 :            : 
     192                 :            :         /* trailing space is not supported */
     193         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0);
     194                 :            : 
     195                 :            :         /* Group must be unsigned */
     196         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0);
     197                 :            : 
     198                 :            :         /* oss-fuzz #6884 */
     199         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "\xff") < 0);
     200                 :          4 : }
     201                 :            : 
     202                 :          4 : static void test_socket_address_equal(void) {
     203                 :            :         SocketAddress a, b;
     204                 :            : 
     205         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     206                 :            : 
     207         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     208         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
     209         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     210                 :            : 
     211         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     212         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
     213         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     214                 :            : 
     215         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     216         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "8888") >= 0);
     217         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     218                 :            : 
     219         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     220         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
     221         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     222                 :            : 
     223         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     224         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
     225         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     226                 :            : 
     227         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
     228         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
     229         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     230                 :            : 
     231         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
     232         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
     233         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     234                 :            : 
     235         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "@abstract") >= 0);
     236         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "@abstract") >= 0);
     237         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     238                 :            : 
     239         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
     240         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
     241         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     242                 :            : 
     243         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
     244         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0);
     245         [ -  + ]:          4 :         assert_se(socket_address_equal(&a, &b));
     246         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0);
     247         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     248         [ -  + ]:          4 :         assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0);
     249         [ -  + ]:          4 :         assert_se(!socket_address_equal(&a, &b));
     250                 :          4 : }
     251                 :            : 
     252                 :          4 : static void test_socket_address_get_path(void) {
     253                 :            :         SocketAddress a;
     254                 :            : 
     255         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     256                 :            : 
     257         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     258         [ -  + ]:          4 :         assert_se(!socket_address_get_path(&a));
     259                 :            : 
     260         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "@abstract") >= 0);
     261         [ -  + ]:          4 :         assert_se(!socket_address_get_path(&a));
     262                 :            : 
     263         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
     264         [ -  + ]:          4 :         assert_se(!socket_address_get_path(&a));
     265                 :            : 
     266         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
     267         [ -  + ]:          4 :         assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
     268                 :            : 
     269         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
     270         [ -  + ]:          4 :         assert_se(!socket_address_get_path(&a));
     271                 :          4 : }
     272                 :            : 
     273                 :          4 : static void test_socket_address_is(void) {
     274                 :            :         SocketAddress a;
     275                 :            : 
     276         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     277                 :            : 
     278         [ -  + ]:          4 :         assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
     279         [ -  + ]:          4 :         assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
     280         [ -  + ]:          4 :         assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
     281         [ -  + ]:          4 :         assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
     282                 :          4 : }
     283                 :            : 
     284                 :          4 : static void test_socket_address_is_netlink(void) {
     285                 :            :         SocketAddress a;
     286                 :            : 
     287         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     288                 :            : 
     289         [ -  + ]:          4 :         assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
     290         [ -  + ]:          4 :         assert_se(socket_address_is_netlink(&a, "route 10"));
     291         [ -  + ]:          4 :         assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888"));
     292         [ -  + ]:          4 :         assert_se(!socket_address_is_netlink(&a, "route 1"));
     293                 :          4 : }
     294                 :            : 
     295                 :          4 : static void test_in_addr_is_null(void) {
     296                 :          4 :         union in_addr_union i = {};
     297                 :            : 
     298         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     299                 :            : 
     300         [ -  + ]:          4 :         assert_se(in_addr_is_null(AF_INET, &i) == true);
     301         [ -  + ]:          4 :         assert_se(in_addr_is_null(AF_INET6, &i) == true);
     302                 :            : 
     303                 :          4 :         i.in.s_addr = 0x1000000;
     304         [ -  + ]:          4 :         assert_se(in_addr_is_null(AF_INET, &i) == false);
     305         [ -  + ]:          4 :         assert_se(in_addr_is_null(AF_INET6, &i) == false);
     306                 :            : 
     307         [ -  + ]:          4 :         assert_se(in_addr_is_null(-1, &i) == -EAFNOSUPPORT);
     308                 :          4 : }
     309                 :            : 
     310                 :         72 : static void test_in_addr_prefix_intersect_one(unsigned f, const char *a, unsigned apl, const char *b, unsigned bpl, int result) {
     311                 :            :         union in_addr_union ua, ub;
     312                 :            : 
     313         [ -  + ]:         72 :         assert_se(in_addr_from_string(f, a, &ua) >= 0);
     314         [ -  + ]:         72 :         assert_se(in_addr_from_string(f, b, &ub) >= 0);
     315                 :            : 
     316         [ -  + ]:         72 :         assert_se(in_addr_prefix_intersect(f, &ua, apl, &ub, bpl) == result);
     317                 :         72 : }
     318                 :            : 
     319                 :          4 : static void test_in_addr_prefix_intersect(void) {
     320         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     321                 :            : 
     322                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 32, "255.255.255.254", 32, 0);
     323                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 0, "255.255.255.255", 32, 1);
     324                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "0.0.0.0", 0, "47.11.8.15", 32, 1);
     325                 :            : 
     326                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.1", 24, 1);
     327                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "2.2.2.2", 24, "1.1.1.1", 24, 0);
     328                 :            : 
     329                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 25, 1);
     330                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 26, 1);
     331                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.127", 25, 1);
     332                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.255", 25, 0);
     333                 :            : 
     334                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 128, 0);
     335                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1);
     336                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "::", 0, "beef:beef:beef:beef:beef:beef:beef:beef", 128, 1);
     337                 :            : 
     338                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "1::2", 64, "1::2", 64, 1);
     339                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "2::2", 64, "1::2", 64, 0);
     340                 :            : 
     341                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 121, 1);
     342                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 122, 1);
     343                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::007f", 121, 1);
     344                 :          4 :         test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::00ff", 121, 0);
     345                 :          4 : }
     346                 :            : 
     347                 :         56 : static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) {
     348                 :            :         union in_addr_union ubefore, uafter, t;
     349                 :            : 
     350         [ -  + ]:         56 :         assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
     351                 :            : 
     352                 :         56 :         t = ubefore;
     353         [ -  + ]:         56 :         assert_se((in_addr_prefix_next(f, &t, pl) > 0) == !!after);
     354                 :            : 
     355         [ +  + ]:         56 :         if (after) {
     356         [ -  + ]:         40 :                 assert_se(in_addr_from_string(f, after, &uafter) >= 0);
     357         [ -  + ]:         40 :                 assert_se(in_addr_equal(f, &t, &uafter) > 0);
     358                 :            :         }
     359                 :         56 : }
     360                 :            : 
     361                 :          4 : static void test_in_addr_prefix_next(void) {
     362         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     363                 :            : 
     364                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0");
     365                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0");
     366                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0");
     367                 :            : 
     368                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1");
     369                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL);
     370                 :          4 :         test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL);
     371                 :            : 
     372                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "4400::", 128, "4400::0001");
     373                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "4400::", 120, "4400::0100");
     374                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "4400::", 127, "4400::0002");
     375                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "4400::", 8, "4500::");
     376                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "4400::", 7, "4600::");
     377                 :            : 
     378                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "::", 128, "::1");
     379                 :            : 
     380                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, NULL);
     381                 :          4 :         test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00", 120, NULL);
     382                 :          4 : }
     383                 :            : 
     384                 :         20 : static void test_in_addr_to_string_one(int f, const char *addr) {
     385                 :            :         union in_addr_union ua;
     386                 :         20 :         _cleanup_free_ char *r = NULL;
     387                 :            : 
     388         [ -  + ]:         20 :         assert_se(in_addr_from_string(f, addr, &ua) >= 0);
     389         [ -  + ]:         20 :         assert_se(in_addr_to_string(f, &ua, &r) >= 0);
     390                 :         20 :         printf("test_in_addr_to_string_one: %s == %s\n", addr, r);
     391         [ -  + ]:         20 :         assert_se(streq(addr, r));
     392                 :         20 : }
     393                 :            : 
     394                 :          4 : static void test_in_addr_to_string(void) {
     395         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     396                 :            : 
     397                 :          4 :         test_in_addr_to_string_one(AF_INET, "192.168.0.1");
     398                 :          4 :         test_in_addr_to_string_one(AF_INET, "10.11.12.13");
     399                 :          4 :         test_in_addr_to_string_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
     400                 :          4 :         test_in_addr_to_string_one(AF_INET6, "::1");
     401                 :          4 :         test_in_addr_to_string_one(AF_INET6, "fe80::");
     402                 :          4 : }
     403                 :            : 
     404                 :         36 : static void test_in_addr_ifindex_to_string_one(int f, const char *a, int ifindex, const char *b) {
     405                 :         36 :         _cleanup_free_ char *r = NULL;
     406                 :            :         union in_addr_union ua, uuaa;
     407                 :            :         int ff, ifindex2;
     408                 :            : 
     409         [ -  + ]:         36 :         assert_se(in_addr_from_string(f, a, &ua) >= 0);
     410         [ -  + ]:         36 :         assert_se(in_addr_ifindex_to_string(f, &ua, ifindex, &r) >= 0);
     411                 :         36 :         printf("test_in_addr_ifindex_to_string_one: %s == %s\n", b, r);
     412         [ -  + ]:         36 :         assert_se(streq(b, r));
     413                 :            : 
     414         [ -  + ]:         36 :         assert_se(in_addr_ifindex_from_string_auto(b, &ff, &uuaa, &ifindex2) >= 0);
     415         [ -  + ]:         36 :         assert_se(ff == f);
     416         [ -  + ]:         36 :         assert_se(in_addr_equal(f, &ua, &uuaa));
     417   [ +  +  -  + ]:         36 :         assert_se(ifindex2 == ifindex || ifindex2 == 0);
     418                 :         36 : }
     419                 :            : 
     420                 :          4 : static void test_in_addr_ifindex_to_string(void) {
     421         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     422                 :            : 
     423                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET, "192.168.0.1", 7, "192.168.0.1");
     424                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET, "10.11.12.13", 9, "10.11.12.13");
     425                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 10, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
     426                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "::1", 11, "::1");
     427                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::", 12, "fe80::%12");
     428                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::", 0, "fe80::");
     429                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::14", 12, "fe80::14%12");
     430                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::15", -7, "fe80::15");
     431                 :          4 :         test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::16", LOOPBACK_IFINDEX, "fe80::16%1");
     432                 :          4 : }
     433                 :            : 
     434                 :          4 : static void test_in_addr_ifindex_from_string_auto(void) {
     435                 :            :         int family, ifindex;
     436                 :            :         union in_addr_union ua;
     437                 :            : 
     438         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     439                 :            :         /* Most in_addr_ifindex_from_string_auto() invocations have already been tested above, but let's test some more */
     440                 :            : 
     441         [ -  + ]:          4 :         assert_se(in_addr_ifindex_from_string_auto("fe80::17", &family, &ua, &ifindex) >= 0);
     442         [ -  + ]:          4 :         assert_se(family == AF_INET6);
     443         [ -  + ]:          4 :         assert_se(ifindex == 0);
     444                 :            : 
     445         [ -  + ]:          4 :         assert_se(in_addr_ifindex_from_string_auto("fe80::18%19", &family, &ua, &ifindex) >= 0);
     446         [ -  + ]:          4 :         assert_se(family == AF_INET6);
     447         [ -  + ]:          4 :         assert_se(ifindex == 19);
     448                 :            : 
     449         [ -  + ]:          4 :         assert_se(in_addr_ifindex_from_string_auto("fe80::18%lo", &family, &ua, &ifindex) >= 0);
     450         [ -  + ]:          4 :         assert_se(family == AF_INET6);
     451         [ -  + ]:          4 :         assert_se(ifindex == LOOPBACK_IFINDEX);
     452                 :            : 
     453         [ -  + ]:          4 :         assert_se(in_addr_ifindex_from_string_auto("fe80::19%thisinterfacecantexist", &family, &ua, &ifindex) == -ENODEV);
     454                 :          4 : }
     455                 :            : 
     456                 :          4 : static void test_sockaddr_equal(void) {
     457                 :          8 :         union sockaddr_union a = {
     458                 :            :                 .in.sin_family = AF_INET,
     459                 :            :                 .in.sin_port = 0,
     460                 :          4 :                 .in.sin_addr.s_addr = htobe32(INADDR_ANY),
     461                 :            :         };
     462                 :          8 :         union sockaddr_union b = {
     463                 :            :                 .in.sin_family = AF_INET,
     464                 :            :                 .in.sin_port = 0,
     465                 :          4 :                 .in.sin_addr.s_addr = htobe32(INADDR_ANY),
     466                 :            :         };
     467                 :          8 :         union sockaddr_union c = {
     468                 :            :                 .in.sin_family = AF_INET,
     469                 :            :                 .in.sin_port = 0,
     470                 :          4 :                 .in.sin_addr.s_addr = htobe32(1234),
     471                 :            :         };
     472                 :          4 :         union sockaddr_union d = {
     473                 :            :                 .in6.sin6_family = AF_INET6,
     474                 :            :                 .in6.sin6_port = 0,
     475                 :            :                 .in6.sin6_addr = IN6ADDR_ANY_INIT,
     476                 :            :         };
     477                 :          4 :         union sockaddr_union e = {
     478                 :            :                 .vm.svm_family = AF_VSOCK,
     479                 :            :                 .vm.svm_port = 0,
     480                 :            :                 .vm.svm_cid = VMADDR_CID_ANY,
     481                 :            :         };
     482                 :            : 
     483         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     484                 :            : 
     485         [ -  + ]:          4 :         assert_se(sockaddr_equal(&a, &a));
     486         [ -  + ]:          4 :         assert_se(sockaddr_equal(&a, &b));
     487         [ -  + ]:          4 :         assert_se(sockaddr_equal(&d, &d));
     488         [ -  + ]:          4 :         assert_se(sockaddr_equal(&e, &e));
     489         [ -  + ]:          4 :         assert_se(!sockaddr_equal(&a, &c));
     490         [ -  + ]:          4 :         assert_se(!sockaddr_equal(&b, &c));
     491         [ -  + ]:          4 :         assert_se(!sockaddr_equal(&a, &e));
     492                 :          4 : }
     493                 :            : 
     494                 :          4 : static void test_sockaddr_un_len(void) {
     495         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     496                 :            : 
     497                 :            :         static const struct sockaddr_un fs = {
     498                 :            :                 .sun_family = AF_UNIX,
     499                 :            :                 .sun_path = "/foo/bar/waldo",
     500                 :            :         };
     501                 :            : 
     502                 :            :         static const struct sockaddr_un abstract = {
     503                 :            :                 .sun_family = AF_UNIX,
     504                 :            :                 .sun_path = "\0foobar",
     505                 :            :         };
     506                 :            : 
     507   [ -  +  -  +  :          4 :         assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path) + 1);
                   -  + ]
     508   [ -  +  +  -  :          4 :         assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
                   -  + ]
     509                 :          4 : }
     510                 :            : 
     511                 :          4 : static void test_in_addr_is_multicast(void) {
     512                 :            :         union in_addr_union a, b;
     513                 :            :         int f;
     514                 :            : 
     515         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     516                 :            : 
     517         [ -  + ]:          4 :         assert_se(in_addr_from_string_auto("192.168.3.11", &f, &a) >= 0);
     518         [ -  + ]:          4 :         assert_se(in_addr_is_multicast(f, &a) == 0);
     519                 :            : 
     520         [ -  + ]:          4 :         assert_se(in_addr_from_string_auto("224.0.0.1", &f, &a) >= 0);
     521         [ -  + ]:          4 :         assert_se(in_addr_is_multicast(f, &a) == 1);
     522                 :            : 
     523         [ -  + ]:          4 :         assert_se(in_addr_from_string_auto("FF01:0:0:0:0:0:0:1", &f, &b) >= 0);
     524         [ -  + ]:          4 :         assert_se(in_addr_is_multicast(f, &b) == 1);
     525                 :            : 
     526         [ -  + ]:          4 :         assert_se(in_addr_from_string_auto("2001:db8::c:69b:aeff:fe53:743e", &f, &b) >= 0);
     527         [ -  + ]:          4 :         assert_se(in_addr_is_multicast(f, &b) == 0);
     528                 :          4 : }
     529                 :            : 
     530                 :          4 : static void test_getpeercred_getpeergroups(void) {
     531                 :            :         int r;
     532                 :            : 
     533         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     534                 :            : 
     535                 :          4 :         r = safe_fork("(getpeercred)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     536         [ -  + ]:          4 :         assert_se(r >= 0);
     537                 :            : 
     538         [ -  + ]:          4 :         if (r == 0) {
     539                 :            :                 static const gid_t gids[] = { 3, 4, 5, 6, 7 };
     540                 :            :                 gid_t *test_gids;
     541                 :            :                 size_t n_test_gids;
     542                 :            :                 uid_t test_uid;
     543                 :            :                 gid_t test_gid;
     544                 :            :                 struct ucred ucred;
     545                 :            :                 int pair[2];
     546                 :            : 
     547         [ #  # ]:          0 :                 if (geteuid() == 0) {
     548                 :          0 :                         test_uid = 1;
     549                 :          0 :                         test_gid = 2;
     550                 :          0 :                         test_gids = (gid_t*) gids;
     551                 :          0 :                         n_test_gids = ELEMENTSOF(gids);
     552                 :            : 
     553         [ #  # ]:          0 :                         assert_se(setgroups(n_test_gids, test_gids) >= 0);
     554         [ #  # ]:          0 :                         assert_se(setresgid(test_gid, test_gid, test_gid) >= 0);
     555         [ #  # ]:          0 :                         assert_se(setresuid(test_uid, test_uid, test_uid) >= 0);
     556                 :            : 
     557                 :            :                 } else {
     558                 :            :                         long ngroups_max;
     559                 :            : 
     560                 :          0 :                         test_uid = getuid();
     561                 :          0 :                         test_gid = getgid();
     562                 :            : 
     563                 :          0 :                         ngroups_max = sysconf(_SC_NGROUPS_MAX);
     564         [ #  # ]:          0 :                         assert(ngroups_max > 0);
     565                 :            : 
     566   [ #  #  #  # ]:          0 :                         test_gids = newa(gid_t, ngroups_max);
     567                 :            : 
     568                 :          0 :                         r = getgroups(ngroups_max, test_gids);
     569         [ #  # ]:          0 :                         assert_se(r >= 0);
     570                 :          0 :                         n_test_gids = (size_t) r;
     571                 :            :                 }
     572                 :            : 
     573         [ #  # ]:          0 :                 assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) >= 0);
     574                 :            : 
     575         [ #  # ]:          0 :                 assert_se(getpeercred(pair[0], &ucred) >= 0);
     576                 :            : 
     577         [ #  # ]:          0 :                 assert_se(ucred.uid == test_uid);
     578         [ #  # ]:          0 :                 assert_se(ucred.gid == test_gid);
     579         [ #  # ]:          0 :                 assert_se(ucred.pid == getpid_cached());
     580                 :            : 
     581                 :            :                 {
     582                 :          0 :                         _cleanup_free_ gid_t *peer_groups = NULL;
     583                 :            : 
     584                 :          0 :                         r = getpeergroups(pair[0], &peer_groups);
     585   [ #  #  #  #  :          0 :                         assert_se(r >= 0 || IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT));
                   #  # ]
     586                 :            : 
     587         [ #  # ]:          0 :                         if (r >= 0) {
     588         [ #  # ]:          0 :                                 assert_se((size_t) r == n_test_gids);
     589         [ #  # ]:          0 :                                 assert_se(memcmp(peer_groups, test_gids, sizeof(gid_t) * n_test_gids) == 0);
     590                 :            :                         }
     591                 :            :                 }
     592                 :            : 
     593                 :          0 :                 safe_close_pair(pair);
     594                 :          0 :                 _exit(EXIT_SUCCESS);
     595                 :            :         }
     596                 :          4 : }
     597                 :            : 
     598                 :          4 : static void test_passfd_read(void) {
     599                 :            :         static const char file_contents[] = "test contents for passfd";
     600                 :          4 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
     601                 :            :         int r;
     602                 :            : 
     603         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     604                 :            : 
     605         [ -  + ]:          4 :         assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
     606                 :            : 
     607                 :          4 :         r = safe_fork("(passfd_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     608         [ -  + ]:          4 :         assert_se(r >= 0);
     609                 :            : 
     610         [ -  + ]:          4 :         if (r == 0) {
     611                 :            :                 /* Child */
     612                 :          0 :                 char tmpfile[] = "/tmp/test-socket-util-passfd-read-XXXXXX";
     613                 :          0 :                 _cleanup_close_ int tmpfd = -1;
     614                 :            : 
     615                 :          0 :                 pair[0] = safe_close(pair[0]);
     616                 :            : 
     617                 :          0 :                 tmpfd = mkostemp_safe(tmpfile);
     618         [ #  # ]:          0 :                 assert_se(tmpfd >= 0);
     619         [ #  # ]:          0 :                 assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents));
     620                 :          0 :                 tmpfd = safe_close(tmpfd);
     621                 :            : 
     622                 :          0 :                 tmpfd = open(tmpfile, O_RDONLY);
     623         [ #  # ]:          0 :                 assert_se(tmpfd >= 0);
     624         [ #  # ]:          0 :                 assert_se(unlink(tmpfile) == 0);
     625                 :            : 
     626         [ #  # ]:          0 :                 assert_se(send_one_fd(pair[1], tmpfd, MSG_DONTWAIT) == 0);
     627                 :          0 :                 _exit(EXIT_SUCCESS);
     628                 :            :         }
     629                 :            : 
     630                 :            :         /* Parent */
     631                 :            :         char buf[64];
     632                 :          4 :         struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1);
     633                 :          4 :         _cleanup_close_ int fd = -1;
     634                 :            : 
     635                 :          4 :         pair[1] = safe_close(pair[1]);
     636                 :            : 
     637         [ -  + ]:          4 :         assert_se(receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd) == 0);
     638                 :            : 
     639         [ -  + ]:          4 :         assert_se(fd >= 0);
     640                 :          4 :         r = read(fd, buf, sizeof(buf)-1);
     641         [ -  + ]:          4 :         assert_se(r >= 0);
     642                 :          4 :         buf[r] = 0;
     643         [ -  + ]:          4 :         assert_se(streq(buf, file_contents));
     644                 :          4 : }
     645                 :            : 
     646                 :          4 : static void test_passfd_contents_read(void) {
     647                 :          4 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
     648                 :            :         static const char file_contents[] = "test contents in the file";
     649                 :            :         static const char wire_contents[] = "test contents on the wire";
     650                 :            :         int r;
     651                 :            : 
     652         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     653                 :            : 
     654         [ -  + ]:          4 :         assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
     655                 :            : 
     656                 :          4 :         r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     657         [ -  + ]:          4 :         assert_se(r >= 0);
     658                 :            : 
     659         [ -  + ]:          4 :         if (r == 0) {
     660                 :            :                 /* Child */
     661                 :          0 :                 struct iovec iov = IOVEC_INIT_STRING(wire_contents);
     662                 :          0 :                 char tmpfile[] = "/tmp/test-socket-util-passfd-contents-read-XXXXXX";
     663                 :          0 :                 _cleanup_close_ int tmpfd = -1;
     664                 :            : 
     665                 :          0 :                 pair[0] = safe_close(pair[0]);
     666                 :            : 
     667                 :          0 :                 tmpfd = mkostemp_safe(tmpfile);
     668         [ #  # ]:          0 :                 assert_se(tmpfd >= 0);
     669         [ #  # ]:          0 :                 assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents));
     670                 :          0 :                 tmpfd = safe_close(tmpfd);
     671                 :            : 
     672                 :          0 :                 tmpfd = open(tmpfile, O_RDONLY);
     673         [ #  # ]:          0 :                 assert_se(tmpfd >= 0);
     674         [ #  # ]:          0 :                 assert_se(unlink(tmpfile) == 0);
     675                 :            : 
     676         [ #  # ]:          0 :                 assert_se(send_one_fd_iov(pair[1], tmpfd, &iov, 1, MSG_DONTWAIT) > 0);
     677                 :          0 :                 _exit(EXIT_SUCCESS);
     678                 :            :         }
     679                 :            : 
     680                 :            :         /* Parent */
     681                 :            :         char buf[64];
     682                 :          4 :         struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1);
     683                 :          4 :         _cleanup_close_ int fd = -1;
     684                 :            :         ssize_t k;
     685                 :            : 
     686                 :          4 :         pair[1] = safe_close(pair[1]);
     687                 :            : 
     688                 :          4 :         k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd);
     689         [ -  + ]:          4 :         assert_se(k > 0);
     690                 :          4 :         buf[k] = 0;
     691         [ -  + ]:          4 :         assert_se(streq(buf, wire_contents));
     692                 :            : 
     693         [ -  + ]:          4 :         assert_se(fd >= 0);
     694                 :          4 :         r = read(fd, buf, sizeof(buf)-1);
     695         [ -  + ]:          4 :         assert_se(r >= 0);
     696                 :          4 :         buf[r] = 0;
     697         [ -  + ]:          4 :         assert_se(streq(buf, file_contents));
     698                 :          4 : }
     699                 :            : 
     700                 :          4 : static void test_receive_nopassfd(void) {
     701                 :          4 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
     702                 :            :         static const char wire_contents[] = "no fd passed here";
     703                 :            :         int r;
     704                 :            : 
     705         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     706                 :            : 
     707         [ -  + ]:          4 :         assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
     708                 :            : 
     709                 :          4 :         r = safe_fork("(receive_nopassfd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     710         [ -  + ]:          4 :         assert_se(r >= 0);
     711                 :            : 
     712         [ -  + ]:          4 :         if (r == 0) {
     713                 :            :                 /* Child */
     714                 :          0 :                 struct iovec iov = IOVEC_INIT_STRING(wire_contents);
     715                 :            : 
     716                 :          0 :                 pair[0] = safe_close(pair[0]);
     717                 :            : 
     718         [ #  # ]:          0 :                 assert_se(send_one_fd_iov(pair[1], -1, &iov, 1, MSG_DONTWAIT) > 0);
     719                 :          0 :                 _exit(EXIT_SUCCESS);
     720                 :            :         }
     721                 :            : 
     722                 :            :         /* Parent */
     723                 :            :         char buf[64];
     724                 :          4 :         struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1);
     725                 :          4 :         int fd = -999;
     726                 :            :         ssize_t k;
     727                 :            : 
     728                 :          4 :         pair[1] = safe_close(pair[1]);
     729                 :            : 
     730                 :          4 :         k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd);
     731         [ -  + ]:          4 :         assert_se(k > 0);
     732                 :          4 :         buf[k] = 0;
     733         [ -  + ]:          4 :         assert_se(streq(buf, wire_contents));
     734                 :            : 
     735                 :            :         /* no fd passed here, confirm it was reset */
     736         [ -  + ]:          4 :         assert_se(fd == -1);
     737                 :          4 : }
     738                 :            : 
     739                 :          4 : static void test_send_nodata_nofd(void) {
     740                 :          4 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
     741                 :            :         int r;
     742                 :            : 
     743         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     744                 :            : 
     745         [ -  + ]:          4 :         assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
     746                 :            : 
     747                 :          4 :         r = safe_fork("(send_nodata_nofd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     748         [ -  + ]:          4 :         assert_se(r >= 0);
     749                 :            : 
     750         [ -  + ]:          4 :         if (r == 0) {
     751                 :            :                 /* Child */
     752                 :          0 :                 pair[0] = safe_close(pair[0]);
     753                 :            : 
     754         [ #  # ]:          0 :                 assert_se(send_one_fd_iov(pair[1], -1, NULL, 0, MSG_DONTWAIT) == -EINVAL);
     755                 :          0 :                 _exit(EXIT_SUCCESS);
     756                 :            :         }
     757                 :            : 
     758                 :            :         /* Parent */
     759                 :            :         char buf[64];
     760                 :          4 :         struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1);
     761                 :          4 :         int fd = -999;
     762                 :            :         ssize_t k;
     763                 :            : 
     764                 :          4 :         pair[1] = safe_close(pair[1]);
     765                 :            : 
     766                 :          4 :         k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd);
     767                 :            :         /* recvmsg() will return errno EAGAIN if nothing was sent */
     768         [ -  + ]:          4 :         assert_se(k == -EAGAIN);
     769                 :            : 
     770                 :            :         /* receive_one_fd_iov returned error, so confirm &fd wasn't touched */
     771         [ -  + ]:          4 :         assert_se(fd == -999);
     772                 :          4 : }
     773                 :            : 
     774                 :          4 : static void test_send_emptydata(void) {
     775                 :          4 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
     776                 :            :         int r;
     777                 :            : 
     778         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     779                 :            : 
     780         [ -  + ]:          4 :         assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
     781                 :            : 
     782                 :          4 :         r = safe_fork("(send_emptydata)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
     783         [ -  + ]:          4 :         assert_se(r >= 0);
     784                 :            : 
     785         [ -  + ]:          4 :         if (r == 0) {
     786                 :            :                 /* Child */
     787                 :          0 :                 struct iovec iov = IOVEC_INIT_STRING("");  /* zero-length iov */
     788         [ #  # ]:          0 :                 assert_se(iov.iov_len == 0);
     789                 :            : 
     790                 :          0 :                 pair[0] = safe_close(pair[0]);
     791                 :            : 
     792                 :            :                 /* This will succeed, since iov is set. */
     793         [ #  # ]:          0 :                 assert_se(send_one_fd_iov(pair[1], -1, &iov, 1, MSG_DONTWAIT) == 0);
     794                 :          0 :                 _exit(EXIT_SUCCESS);
     795                 :            :         }
     796                 :            : 
     797                 :            :         /* Parent */
     798                 :            :         char buf[64];
     799                 :          4 :         struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1);
     800                 :          4 :         int fd = -999;
     801                 :            :         ssize_t k;
     802                 :            : 
     803                 :          4 :         pair[1] = safe_close(pair[1]);
     804                 :            : 
     805                 :          4 :         k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd);
     806                 :            :         /* receive_one_fd_iov() returns -EIO if an fd is not found and no data was returned. */
     807         [ -  + ]:          4 :         assert_se(k == -EIO);
     808                 :            : 
     809                 :            :         /* receive_one_fd_iov returned error, so confirm &fd wasn't touched */
     810         [ -  + ]:          4 :         assert_se(fd == -999);
     811                 :          4 : }
     812                 :            : 
     813                 :          4 : static void test_flush_accept(void) {
     814                 :          4 :         _cleanup_close_ int listen_stream = -1, listen_dgram = -1, listen_seqpacket = 1, connect_stream = -1, connect_dgram = -1, connect_seqpacket = -1;
     815                 :            :         static const union sockaddr_union sa = { .un.sun_family = AF_UNIX };
     816                 :            :         union sockaddr_union lsa;
     817                 :            :         socklen_t l;
     818                 :            : 
     819                 :          4 :         listen_stream = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     820         [ -  + ]:          4 :         assert_se(listen_stream >= 0);
     821                 :            : 
     822                 :          4 :         listen_dgram = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     823         [ -  + ]:          4 :         assert_se(listen_dgram >= 0);
     824                 :            : 
     825                 :          4 :         listen_seqpacket = socket(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     826         [ -  + ]:          4 :         assert_se(listen_seqpacket >= 0);
     827                 :            : 
     828         [ -  + ]:          4 :         assert_se(flush_accept(listen_stream) < 0);
     829         [ -  + ]:          4 :         assert_se(flush_accept(listen_dgram) < 0);
     830         [ -  + ]:          4 :         assert_se(flush_accept(listen_seqpacket) < 0);
     831                 :            : 
     832         [ -  + ]:          4 :         assert_se(bind(listen_stream, &sa.sa, sizeof(sa_family_t)) >= 0);
     833         [ -  + ]:          4 :         assert_se(bind(listen_dgram, &sa.sa, sizeof(sa_family_t)) >= 0);
     834         [ -  + ]:          4 :         assert_se(bind(listen_seqpacket, &sa.sa, sizeof(sa_family_t)) >= 0);
     835                 :            : 
     836         [ -  + ]:          4 :         assert_se(flush_accept(listen_stream) < 0);
     837         [ -  + ]:          4 :         assert_se(flush_accept(listen_dgram) < 0);
     838         [ -  + ]:          4 :         assert_se(flush_accept(listen_seqpacket) < 0);
     839                 :            : 
     840         [ -  + ]:          4 :         assert_se(listen(listen_stream, SOMAXCONN) >= 0);
     841         [ -  + ]:          4 :         assert_se(listen(listen_dgram, SOMAXCONN) < 0);
     842         [ -  + ]:          4 :         assert_se(listen(listen_seqpacket, SOMAXCONN) >= 0);
     843                 :            : 
     844         [ -  + ]:          4 :         assert_se(flush_accept(listen_stream) >= 0);
     845         [ -  + ]:          4 :         assert_se(flush_accept(listen_dgram) < 0);
     846         [ -  + ]:          4 :         assert_se(flush_accept(listen_seqpacket) >= 0);
     847                 :            : 
     848                 :          4 :         connect_stream = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     849         [ -  + ]:          4 :         assert_se(connect_stream >= 0);
     850                 :            : 
     851                 :          4 :         connect_dgram = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     852         [ -  + ]:          4 :         assert_se(connect_dgram >= 0);
     853                 :            : 
     854                 :          4 :         connect_seqpacket = socket(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     855         [ -  + ]:          4 :         assert_se(connect_seqpacket >= 0);
     856                 :            : 
     857                 :          4 :         l = sizeof(lsa);
     858         [ -  + ]:          4 :         assert_se(getsockname(listen_stream, &lsa.sa, &l) >= 0);
     859         [ -  + ]:          4 :         assert_se(connect(connect_stream, &lsa.sa, l) >= 0);
     860                 :            : 
     861                 :          4 :         l = sizeof(lsa);
     862         [ -  + ]:          4 :         assert_se(getsockname(listen_dgram, &lsa.sa, &l) >= 0);
     863         [ -  + ]:          4 :         assert_se(connect(connect_dgram, &lsa.sa, l) >= 0);
     864                 :            : 
     865                 :          4 :         l = sizeof(lsa);
     866         [ -  + ]:          4 :         assert_se(getsockname(listen_seqpacket, &lsa.sa, &l) >= 0);
     867         [ -  + ]:          4 :         assert_se(connect(connect_seqpacket, &lsa.sa, l) >= 0);
     868                 :            : 
     869         [ -  + ]:          4 :         assert_se(flush_accept(listen_stream) >= 0);
     870         [ -  + ]:          4 :         assert_se(flush_accept(listen_dgram) < 0);
     871         [ -  + ]:          4 :         assert_se(flush_accept(listen_seqpacket) >= 0);
     872                 :          4 : }
     873                 :            : 
     874                 :          4 : int main(int argc, char *argv[]) {
     875                 :          4 :         test_setup_logging(LOG_DEBUG);
     876                 :            : 
     877                 :          4 :         test_ifname_valid();
     878                 :            : 
     879                 :          4 :         test_socket_address_parse();
     880                 :          4 :         test_socket_print_unix();
     881                 :          4 :         test_socket_address_parse_netlink();
     882                 :          4 :         test_socket_address_equal();
     883                 :          4 :         test_socket_address_get_path();
     884                 :          4 :         test_socket_address_is();
     885                 :          4 :         test_socket_address_is_netlink();
     886                 :            : 
     887                 :          4 :         test_in_addr_is_null();
     888                 :          4 :         test_in_addr_prefix_intersect();
     889                 :          4 :         test_in_addr_prefix_next();
     890                 :          4 :         test_in_addr_to_string();
     891                 :          4 :         test_in_addr_ifindex_to_string();
     892                 :          4 :         test_in_addr_ifindex_from_string_auto();
     893                 :            : 
     894                 :          4 :         test_sockaddr_equal();
     895                 :            : 
     896                 :          4 :         test_sockaddr_un_len();
     897                 :            : 
     898                 :          4 :         test_in_addr_is_multicast();
     899                 :            : 
     900                 :          4 :         test_getpeercred_getpeergroups();
     901                 :            : 
     902                 :          4 :         test_passfd_read();
     903                 :          4 :         test_passfd_contents_read();
     904                 :          4 :         test_receive_nopassfd();
     905                 :          4 :         test_send_nodata_nofd();
     906                 :          4 :         test_send_emptydata();
     907                 :          4 :         test_flush_accept();
     908                 :            : 
     909                 :          4 :         return 0;
     910                 :            : }

Generated by: LCOV version 1.14