LCOV - code coverage report
Current view: top level - fuzz - fuzz-varlink.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 70 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 5 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 76 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <unistd.h>
       4                 :            : 
       5                 :            : #include "errno-util.h"
       6                 :            : #include "fd-util.h"
       7                 :            : #include "fuzz.h"
       8                 :            : #include "hexdecoct.h"
       9                 :            : #include "io-util.h"
      10                 :            : #include "varlink.h"
      11                 :            : #include "log.h"
      12                 :            : 
      13                 :            : static FILE *null = NULL;
      14                 :            : 
      15                 :          0 : static int method_something(Varlink *v, JsonVariant *p, VarlinkMethodFlags flags, void *userdata) {
      16                 :          0 :         json_variant_dump(p, JSON_FORMAT_NEWLINE|JSON_FORMAT_PRETTY, null, NULL);
      17                 :          0 :         return 0;
      18                 :            : }
      19                 :            : 
      20                 :          0 : static int reply_callback(Varlink *v, JsonVariant *p, const char *error_id, VarlinkReplyFlags flags, void *userdata) {
      21                 :          0 :         json_variant_dump(p, JSON_FORMAT_NEWLINE|JSON_FORMAT_PRETTY, null, NULL);
      22                 :          0 :         return 0;
      23                 :            : }
      24                 :            : 
      25                 :          0 : static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
      26                 :          0 :         struct iovec *iov = userdata;
      27                 :          0 :         bool write_eof = false, read_eof = false;
      28                 :            : 
      29         [ #  # ]:          0 :         assert(s);
      30         [ #  # ]:          0 :         assert(fd >= 0);
      31         [ #  # ]:          0 :         assert(iov);
      32                 :            : 
      33   [ #  #  #  # ]:          0 :         if ((revents & (EPOLLOUT|EPOLLHUP|EPOLLERR)) && iov->iov_len > 0) {
      34                 :            :                 ssize_t n;
      35                 :            : 
      36                 :            :                 /* never write more than 143 bytes a time, to make broken up recv()s on the other side more
      37                 :            :                  * likely, and thus test some additional code paths. */
      38                 :          0 :                 n = send(fd, iov->iov_base, MIN(iov->iov_len, 143U), MSG_NOSIGNAL|MSG_DONTWAIT);
      39         [ #  # ]:          0 :                 if (n < 0) {
      40         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(errno))
      41                 :          0 :                                 write_eof = true;
      42                 :            :                         else
      43         [ #  # ]:          0 :                                 assert_se(errno == EAGAIN);
      44                 :            :                 } else
      45                 :          0 :                         IOVEC_INCREMENT(iov, 1, n);
      46                 :            :         }
      47                 :            : 
      48         [ #  # ]:          0 :         if (revents & EPOLLIN) {
      49                 :            :                 char c[137];
      50                 :            :                 ssize_t n;
      51                 :            : 
      52                 :          0 :                 n = recv(fd, c, sizeof(c), MSG_DONTWAIT);
      53         [ #  # ]:          0 :                 if (n < 0) {
      54         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(errno))
      55                 :          0 :                                 read_eof = true;
      56                 :            :                         else
      57         [ #  # ]:          0 :                                 assert_se(errno == EAGAIN);
      58         [ #  # ]:          0 :                 } else if (n == 0)
      59                 :          0 :                         read_eof = true;
      60                 :            :                 else
      61                 :          0 :                         hexdump(null, c, (size_t) n);
      62                 :            :         }
      63                 :            : 
      64                 :            :         /* After we wrote everything we could turn off EPOLLOUT. And if we reached read EOF too turn off the
      65                 :            :          * whole thing. */
      66   [ #  #  #  # ]:          0 :         if (write_eof || iov->iov_len == 0) {
      67                 :            : 
      68         [ #  # ]:          0 :                 if (read_eof)
      69         [ #  # ]:          0 :                         assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
      70                 :            :                 else
      71         [ #  # ]:          0 :                         assert_se(sd_event_source_set_io_events(s, EPOLLIN) >= 0);
      72                 :            :         }
      73                 :            : 
      74                 :          0 :         return 0;
      75                 :            : }
      76                 :            : 
      77                 :          0 : static int idle_callback(sd_event_source *s, void *userdata) {
      78         [ #  # ]:          0 :         assert(s);
      79                 :            : 
      80                 :            :         /* Called as idle callback when there's nothing else to do anymore */
      81                 :          0 :         sd_event_exit(sd_event_source_get_event(s), 0);
      82                 :          0 :         return 0;
      83                 :            : }
      84                 :            : 
      85                 :          0 : int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
      86                 :          0 :         struct iovec server_iov = IOVEC_MAKE((void*) data, size), client_iov = IOVEC_MAKE((void*) data, size);
      87                 :            :         /* Important: the declaration order matters here! we want that the fds are closed on return after the
      88                 :            :          * event sources, hence we declare the fds first, the event sources second */
      89                 :          0 :         _cleanup_close_pair_ int server_pair[2] = { -1, -1 }, client_pair[2] = { -1, -1 };
      90                 :          0 :         _cleanup_(sd_event_source_unrefp) sd_event_source *idle_event_source = NULL,
      91                 :          0 :                 *server_event_source = NULL, *client_event_source = NULL;
      92                 :          0 :         _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
      93                 :          0 :         _cleanup_(varlink_flush_close_unrefp) Varlink *c = NULL;
      94                 :          0 :         _cleanup_(sd_event_unrefp) sd_event *e = NULL;
      95                 :            : 
      96                 :          0 :         log_set_max_level(LOG_CRIT);
      97                 :          0 :         log_parse_environment();
      98                 :            : 
      99         [ #  # ]:          0 :         assert_se(null = fopen("/dev/null", "we"));
     100                 :            : 
     101         [ #  # ]:          0 :         assert_se(sd_event_default(&e) >= 0);
     102                 :            : 
     103                 :            :         /* Test one: write the data as method call to a server */
     104         [ #  # ]:          0 :         assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, server_pair) >= 0);
     105         [ #  # ]:          0 :         assert_se(varlink_server_new(&s, 0) >= 0);
     106         [ #  # ]:          0 :         assert_se(varlink_server_set_description(s, "myserver") >= 0);
     107         [ #  # ]:          0 :         assert_se(varlink_server_attach_event(s, e, 0) >= 0);
     108         [ #  # ]:          0 :         assert_se(varlink_server_add_connection(s, server_pair[0], NULL) >= 0);
     109                 :          0 :         TAKE_FD(server_pair[0]);
     110         [ #  # ]:          0 :         assert_se(varlink_server_bind_method(s, "io.test.DoSomething", method_something) >= 0);
     111         [ #  # ]:          0 :         assert_se(sd_event_add_io(e, &server_event_source, server_pair[1], EPOLLIN|EPOLLOUT, io_callback, &server_iov) >= 0);
     112                 :            : 
     113                 :            :         /* Test two: write the data as method response to a client */
     114         [ #  # ]:          0 :         assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, client_pair) >= 0);
     115         [ #  # ]:          0 :         assert_se(varlink_connect_fd(&c, client_pair[0]) >= 0);
     116                 :          0 :         TAKE_FD(client_pair[0]);
     117         [ #  # ]:          0 :         assert_se(varlink_set_description(c, "myclient") >= 0);
     118         [ #  # ]:          0 :         assert_se(varlink_attach_event(c, e, 0) >= 0);
     119         [ #  # ]:          0 :         assert_se(varlink_bind_reply(c, reply_callback) >= 0);
     120         [ #  # ]:          0 :         assert_se(varlink_invoke(c, "io.test.DoSomething", NULL) >= 0);
     121         [ #  # ]:          0 :         assert_se(sd_event_add_io(e, &client_event_source, client_pair[1], EPOLLIN|EPOLLOUT, io_callback, &client_iov) >= 0);
     122                 :            : 
     123         [ #  # ]:          0 :         assert_se(sd_event_add_defer(e, &idle_event_source, idle_callback, NULL) >= 0);
     124         [ #  # ]:          0 :         assert_se(sd_event_source_set_priority(idle_event_source, SD_EVENT_PRIORITY_IDLE) >= 0);
     125                 :            : 
     126         [ #  # ]:          0 :         assert_se(sd_event_loop(e) >= 0);
     127                 :            : 
     128                 :          0 :         null = safe_fclose(null);
     129                 :            : 
     130                 :          0 :         return 0;
     131                 :            : }

Generated by: LCOV version 1.14