1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "errno-util.h"
13 static FILE *null
= NULL
;
15 static int method_something(Varlink
*v
, JsonVariant
*p
, VarlinkMethodFlags flags
, void *userdata
) {
16 json_variant_dump(p
, JSON_FORMAT_NEWLINE
|JSON_FORMAT_PRETTY
, null
, NULL
);
20 static int reply_callback(Varlink
*v
, JsonVariant
*p
, const char *error_id
, VarlinkReplyFlags flags
, void *userdata
) {
21 json_variant_dump(p
, JSON_FORMAT_NEWLINE
|JSON_FORMAT_PRETTY
, null
, NULL
);
25 static int io_callback(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
26 struct iovec
*iov
= userdata
;
27 bool write_eof
= false, read_eof
= false;
33 if ((revents
& (EPOLLOUT
|EPOLLHUP
|EPOLLERR
)) && iov
->iov_len
> 0) {
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 n
= send(fd
, iov
->iov_base
, MIN(iov
->iov_len
, 143U), MSG_NOSIGNAL
|MSG_DONTWAIT
);
40 if (ERRNO_IS_DISCONNECT(errno
))
43 assert_se(errno
== EAGAIN
);
45 IOVEC_INCREMENT(iov
, 1, n
);
48 if (revents
& EPOLLIN
) {
52 n
= recv(fd
, c
, sizeof(c
), MSG_DONTWAIT
);
54 if (ERRNO_IS_DISCONNECT(errno
))
57 assert_se(errno
== EAGAIN
);
61 hexdump(null
, c
, (size_t) n
);
64 /* After we wrote everything we could turn off EPOLLOUT. And if we reached read EOF too turn off the
66 if (write_eof
|| iov
->iov_len
== 0) {
69 assert_se(sd_event_source_set_enabled(s
, SD_EVENT_OFF
) >= 0);
71 assert_se(sd_event_source_set_io_events(s
, EPOLLIN
) >= 0);
77 static int idle_callback(sd_event_source
*s
, void *userdata
) {
80 /* Called as idle callback when there's nothing else to do anymore */
81 sd_event_exit(sd_event_source_get_event(s
), 0);
85 int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
) {
86 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 _cleanup_close_pair_
int server_pair
[2] = { -1, -1 }, client_pair
[2] = { -1, -1 };
90 _cleanup_(sd_event_source_unrefp
) sd_event_source
*idle_event_source
= NULL
,
91 *server_event_source
= NULL
, *client_event_source
= NULL
;
92 _cleanup_(varlink_server_unrefp
) VarlinkServer
*s
= NULL
;
93 _cleanup_(varlink_flush_close_unrefp
) Varlink
*c
= NULL
;
94 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
96 log_set_max_level(LOG_CRIT
);
97 log_parse_environment();
99 assert_se(null
= fopen("/dev/null", "we"));
101 assert_se(sd_event_default(&e
) >= 0);
103 /* Test one: write the data as method call to a server */
104 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
, 0, server_pair
) >= 0);
105 assert_se(varlink_server_new(&s
, 0) >= 0);
106 assert_se(varlink_server_set_description(s
, "myserver") >= 0);
107 assert_se(varlink_server_attach_event(s
, e
, 0) >= 0);
108 assert_se(varlink_server_add_connection(s
, server_pair
[0], NULL
) >= 0);
109 TAKE_FD(server_pair
[0]);
110 assert_se(varlink_server_bind_method(s
, "io.test.DoSomething", method_something
) >= 0);
111 assert_se(sd_event_add_io(e
, &server_event_source
, server_pair
[1], EPOLLIN
|EPOLLOUT
, io_callback
, &server_iov
) >= 0);
113 /* Test two: write the data as method response to a client */
114 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
, 0, client_pair
) >= 0);
115 assert_se(varlink_connect_fd(&c
, client_pair
[0]) >= 0);
116 TAKE_FD(client_pair
[0]);
117 assert_se(varlink_set_description(c
, "myclient") >= 0);
118 assert_se(varlink_attach_event(c
, e
, 0) >= 0);
119 assert_se(varlink_bind_reply(c
, reply_callback
) >= 0);
120 assert_se(varlink_invoke(c
, "io.test.DoSomething", NULL
) >= 0);
121 assert_se(sd_event_add_io(e
, &client_event_source
, client_pair
[1], EPOLLIN
|EPOLLOUT
, io_callback
, &client_iov
) >= 0);
123 assert_se(sd_event_add_defer(e
, &idle_event_source
, idle_callback
, NULL
) >= 0);
124 assert_se(sd_event_source_set_priority(idle_event_source
, SD_EVENT_PRIORITY_IDLE
) >= 0);
126 assert_se(sd_event_loop(e
) >= 0);
128 null
= safe_fclose(null
);