Bug Summary

File:build-scan/../src/libsystemd/sd-bus/bus-socket.c
Warning:line 792, column 30
Potential leak of memory pointed to by 'prefix'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name bus-socket.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/libsystemd/libsystemd_static.a.p -I src/libsystemd -I ../src/libsystemd -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd/sd-bus/bus-socket.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3***/
4
5#include <endian.h>
6#include <poll.h>
7#include <stdlib.h>
8#include <unistd.h>
9
10#include "sd-bus.h"
11#include "sd-daemon.h"
12
13#include "alloc-util.h"
14#include "bus-internal.h"
15#include "bus-message.h"
16#include "bus-socket.h"
17#include "fd-util.h"
18#include "format-util.h"
19#include "fs-util.h"
20#include "hexdecoct.h"
21#include "io-util.h"
22#include "macro.h"
23#include "missing.h"
24#include "path-util.h"
25#include "process-util.h"
26#include "selinux-util.h"
27#include "signal-util.h"
28#include "stdio-util.h"
29#include "string-util.h"
30#include "user-util.h"
31#include "utf8.h"
32#include "util.h"
33
34#define SNDBUF_SIZE(8*1024*1024) (8*1024*1024)
35
36static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
37
38 while (size > 0) {
39 struct iovec *i = iov + *idx;
40
41 if (i->iov_len > size) {
42 i->iov_base = (uint8_t*) i->iov_base + size;
43 i->iov_len -= size;
44 return;
45 }
46
47 size -= i->iov_len;
48
49 i->iov_base = NULL((void*)0);
50 i->iov_len = 0;
51
52 (*idx)++;
53 }
54}
55
56static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
57 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-bus/bus-socket.c"
, 57, __PRETTY_FUNCTION__); } while (0)
;
58 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/libsystemd/sd-bus/bus-socket.c"
, 58, __PRETTY_FUNCTION__); } while (0)
;
59 assert(sz > 0)do { if ((__builtin_expect(!!(!(sz > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("sz > 0"), "../src/libsystemd/sd-bus/bus-socket.c"
, 59, __PRETTY_FUNCTION__); } while (0)
;
60
61 m->iovec[m->n_iovec].iov_base = (void*) p;
62 m->iovec[m->n_iovec].iov_len = sz;
63 m->n_iovec++;
64
65 return 0;
66}
67
68static int bus_message_setup_iovec(sd_bus_message *m) {
69 struct bus_body_part *part;
70 unsigned n, i;
71 int r;
72
73 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-bus/bus-socket.c"
, 73, __PRETTY_FUNCTION__); } while (0)
;
74 assert(m->sealed)do { if ((__builtin_expect(!!(!(m->sealed)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->sealed"), "../src/libsystemd/sd-bus/bus-socket.c"
, 74, __PRETTY_FUNCTION__); } while (0)
;
75
76 if (m->n_iovec > 0)
77 return 0;
78
79 assert(!m->iovec)do { if ((__builtin_expect(!!(!(!m->iovec)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!m->iovec"), "../src/libsystemd/sd-bus/bus-socket.c"
, 79, __PRETTY_FUNCTION__); } while (0)
;
80
81 n = 1 + m->n_body_parts;
82 if (n < ELEMENTSOF(m->iovec_fixed)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(m->iovec_fixed), typeof(&*(m->iovec_fixed))
), sizeof(m->iovec_fixed)/sizeof((m->iovec_fixed)[0]), (
(void)0)))
)
83 m->iovec = m->iovec_fixed;
84 else {
85 m->iovec = new(struct iovec, n)((struct iovec*) malloc_multiply(sizeof(struct iovec), (n)));
86 if (!m->iovec) {
87 r = -ENOMEM12;
88 goto fail;
89 }
90 }
91
92 r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
93 if (r < 0)
94 goto fail;
95
96 MESSAGE_FOREACH_PART(part, i, m)for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts
; (i)++, (part) = (part)->next)
{
97 r = bus_body_part_map(part);
98 if (r < 0)
99 goto fail;
100
101 r = append_iovec(m, part->data, part->size);
102 if (r < 0)
103 goto fail;
104 }
105
106 assert(n == m->n_iovec)do { if ((__builtin_expect(!!(!(n == m->n_iovec)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("n == m->n_iovec"), "../src/libsystemd/sd-bus/bus-socket.c"
, 106, __PRETTY_FUNCTION__); } while (0)
;
107
108 return 0;
109
110fail:
111 m->poisoned = true1;
112 return r;
113}
114
115bool_Bool bus_socket_auth_needs_write(sd_bus *b) {
116
117 unsigned i;
118
119 if (b->auth_index >= ELEMENTSOF(b->auth_iovec)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(b->auth_iovec), typeof(&*(b->auth_iovec))),
sizeof(b->auth_iovec)/sizeof((b->auth_iovec)[0]), ((void
)0)))
)
120 return false0;
121
122 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(b->auth_iovec), typeof(&*(b->auth_iovec))),
sizeof(b->auth_iovec)/sizeof((b->auth_iovec)[0]), ((void
)0)))
; i++) {
123 struct iovec *j = b->auth_iovec + i;
124
125 if (j->iov_len > 0)
126 return true1;
127 }
128
129 return false0;
130}
131
132static int bus_socket_write_auth(sd_bus *b) {
133 ssize_t k;
134
135 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 135, __PRETTY_FUNCTION__); } while (0)
;
136 assert(b->state == BUS_AUTHENTICATING)do { if ((__builtin_expect(!!(!(b->state == BUS_AUTHENTICATING
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->state == BUS_AUTHENTICATING"
), "../src/libsystemd/sd-bus/bus-socket.c", 136, __PRETTY_FUNCTION__
); } while (0)
;
137
138 if (!bus_socket_auth_needs_write(b))
139 return 0;
140
141 if (b->prefer_writev)
142 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(b->auth_iovec), typeof(&*(b->auth_iovec))),
sizeof(b->auth_iovec)/sizeof((b->auth_iovec)[0]), ((void
)0)))
- b->auth_index);
143 else {
144 struct msghdr mh;
145 zero(mh)(({ size_t _l_ = (sizeof(mh)); void *_x_ = (&(mh)); _l_ ==
0 ? _x_ : memset(_x_, 0, _l_); }))
;
146
147 mh.msg_iov = b->auth_iovec + b->auth_index;
148 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(b->auth_iovec), typeof(&*(b->auth_iovec))),
sizeof(b->auth_iovec)/sizeof((b->auth_iovec)[0]), ((void
)0)))
- b->auth_index;
149
150 k = sendmsg(b->output_fd, &mh, MSG_DONTWAITMSG_DONTWAIT|MSG_NOSIGNALMSG_NOSIGNAL);
151 if (k < 0 && errno(*__errno_location ()) == ENOTSOCK88) {
152 b->prefer_writev = true1;
153 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(b->auth_iovec), typeof(&*(b->auth_iovec))),
sizeof(b->auth_iovec)/sizeof((b->auth_iovec)[0]), ((void
)0)))
- b->auth_index);
154 }
155 }
156
157 if (k < 0)
158 return errno(*__errno_location ()) == EAGAIN11 ? 0 : -errno(*__errno_location ());
159
160 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
161 return 1;
162}
163
164static int bus_socket_auth_verify_client(sd_bus *b) {
165 char *d, *e, *f, *start;
166 sd_id128_t peer;
167 unsigned i;
168 int r;
169
170 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 170, __PRETTY_FUNCTION__); } while (0)
;
171
172 /*
173 * We expect three response lines:
174 * "DATA\r\n"
175 * "OK <server-id>\r\n"
176 * "AGREE_UNIX_FD\r\n" (optional)
177 */
178
179 d = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2);
180 if (!d)
181 return 0;
182
183 e = memmem(d + 2, b->rbuffer_size - (d - (char*) b->rbuffer) - 2, "\r\n", 2);
184 if (!e)
185 return 0;
186
187 if (b->accept_fd) {
188 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
189 if (!f)
190 return 0;
191
192 start = f + 2;
193 } else {
194 f = NULL((void*)0);
195 start = e + 2;
196 }
197
198 /* Nice! We got all the lines we need. First check the DATA line. */
199
200 if (d - (char*) b->rbuffer == 4) {
201 if (memcmp(b->rbuffer, "DATA", 4))
202 return -EPERM1;
203 } else if (d - (char*) b->rbuffer == 3 + 32) {
204 /*
205 * Old versions of the server-side implementation of `sd-bus` replied with "OK <id>" to
206 * "AUTH" requests from a client, even if the "AUTH" line did not contain inlined
207 * arguments. Therefore, we also accept "OK <id>" here, even though it is technically the
208 * wrong reply. We ignore the "<id>" parameter, though, since it has no real value.
209 */
210 if (memcmp(b->rbuffer, "OK ", 3))
211 return -EPERM1;
212 } else {
213 return -EPERM1;
214 }
215
216 /* Now check the OK line. */
217
218 if (e - d != 2 + 3 + 32)
219 return -EPERM1;
220
221 if (memcmp(d + 2, "OK ", 3))
222 return -EPERM1;
223
224 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
225
226 for (i = 0; i < 32; i += 2) {
227 int x, y;
228
229 x = unhexchar(d[2 + 3 + i]);
230 y = unhexchar(d[2 + 3 + i + 1]);
231
232 if (x < 0 || y < 0)
233 return -EINVAL22;
234
235 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
236 }
237
238 if (!sd_id128_is_null(b->server_id) &&
239 !sd_id128_equal(b->server_id, peer))
240 return -EPERM1;
241
242 b->server_id = peer;
243
244 /* And possibly check the third line, too */
245
246 if (f)
247 b->can_fds =
248 (f - e == STRLEN("\r\nAGREE_UNIX_FD")(sizeof("""\r\nAGREE_UNIX_FD""") - 1)) &&
249 memcmp(e + 2, "AGREE_UNIX_FD",
250 STRLEN("AGREE_UNIX_FD")(sizeof("""AGREE_UNIX_FD""") - 1)) == 0;
251
252 b->rbuffer_size -= (start - (char*) b->rbuffer);
253 memmove(b->rbuffer, start, b->rbuffer_size);
254
255 r = bus_start_running(b);
256 if (r < 0)
257 return r;
258
259 return 1;
260}
261
262static bool_Bool line_equals(const char *s, size_t m, const char *line) {
263 size_t l;
264
265 l = strlen(line);
266 if (l != m)
267 return false0;
268
269 return memcmp(s, line, l) == 0;
270}
271
272static bool_Bool line_begins(const char *s, size_t m, const char *word) {
273 const char *p;
274
275 p = memory_startswith(s, m, word);
276 return p && (p == (s + m) || *p == ' ');
277}
278
279static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
280 _cleanup_free___attribute__((cleanup(freep))) char *token = NULL((void*)0);
281 size_t len;
282 int r;
283
284 if (!b->anonymous_auth)
285 return 0;
286
287 if (l <= 0)
288 return 1;
289
290 assert(p[0] == ' ')do { if ((__builtin_expect(!!(!(p[0] == ' ')),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p[0] == ' '"), "../src/libsystemd/sd-bus/bus-socket.c"
, 290, __PRETTY_FUNCTION__); } while (0)
;
291 p++; l--;
292
293 if (l % 2 != 0)
294 return 0;
295
296 r = unhexmem(p, l, (void **) &token, &len);
297 if (r < 0)
298 return 0;
299
300 if (memchr(token, 0, len))
301 return 0;
302
303 return !!utf8_is_valid(token);
304}
305
306static int verify_external_token(sd_bus *b, const char *p, size_t l) {
307 _cleanup_free___attribute__((cleanup(freep))) char *token = NULL((void*)0);
308 size_t len;
309 uid_t u;
310 int r;
311
312 /* We don't do any real authentication here. Instead, we if
313 * the owner of this bus wanted authentication he should have
314 * checked SO_PEERCRED before even creating the bus object. */
315
316 if (!b->anonymous_auth && !b->ucred_valid)
317 return 0;
318
319 if (l <= 0)
320 return 1;
321
322 assert(p[0] == ' ')do { if ((__builtin_expect(!!(!(p[0] == ' ')),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p[0] == ' '"), "../src/libsystemd/sd-bus/bus-socket.c"
, 322, __PRETTY_FUNCTION__); } while (0)
;
323 p++; l--;
324
325 if (l % 2 != 0)
326 return 0;
327
328 r = unhexmem(p, l, (void**) &token, &len);
329 if (r < 0)
330 return 0;
331
332 if (memchr(token, 0, len))
333 return 0;
334
335 r = parse_uid(token, &u);
336 if (r < 0)
337 return 0;
338
339 /* We ignore the passed value if anonymous authentication is
340 * on anyway. */
341 if (!b->anonymous_auth && u != b->ucred.uid)
342 return 0;
343
344 return 1;
345}
346
347static int bus_socket_auth_write(sd_bus *b, const char *t) {
348 char *p;
349 size_t l;
350
351 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 351, __PRETTY_FUNCTION__); } while (0)
;
352 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/libsystemd/sd-bus/bus-socket.c"
, 352, __PRETTY_FUNCTION__); } while (0)
;
353
354 /* We only make use of the first iovec */
355 assert(IN_SET(b->auth_index, 0, 1))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){0, 1})/sizeof(int)]; switch(b->auth_index
) { case 0: case 1: _found = 1; break; default: break; } _found
; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(b->auth_index, 0, 1)"
), "../src/libsystemd/sd-bus/bus-socket.c", 355, __PRETTY_FUNCTION__
); } while (0)
;
356
357 l = strlen(t);
358 p = malloc(b->auth_iovec[0].iov_len + l);
359 if (!p)
360 return -ENOMEM12;
361
362 memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
363 memcpy(p + b->auth_iovec[0].iov_len, t, l);
364
365 b->auth_iovec[0].iov_base = p;
366 b->auth_iovec[0].iov_len += l;
367
368 free(b->auth_buffer);
369 b->auth_buffer = p;
370 b->auth_index = 0;
371 return 0;
372}
373
374static int bus_socket_auth_write_ok(sd_bus *b) {
375 char t[3 + 32 + 2 + 1];
376
377 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 377, __PRETTY_FUNCTION__); } while (0)
;
378
379 xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id))do { if ((__builtin_expect(!!(!(((size_t) snprintf(t, __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(t), typeof(&*(t))), sizeof(t)/sizeof((t)[0]), ((void)0))
), "OK " "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
"\r\n", (b->server_id).bytes[0], (b->server_id).bytes[
1], (b->server_id).bytes[2], (b->server_id).bytes[3], (
b->server_id).bytes[4], (b->server_id).bytes[5], (b->
server_id).bytes[6], (b->server_id).bytes[7], (b->server_id
).bytes[8], (b->server_id).bytes[9], (b->server_id).bytes
[10], (b->server_id).bytes[11], (b->server_id).bytes[12
], (b->server_id).bytes[13], (b->server_id).bytes[14], (
b->server_id).bytes[15]) < (__extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(t), typeof(&*(t)))
, sizeof(t)/sizeof((t)[0]), ((void)0))))))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("xsprintf: " "t" "[] must be big enough"
), "../src/libsystemd/sd-bus/bus-socket.c", 379, __PRETTY_FUNCTION__
); } while (0)
;
380
381 return bus_socket_auth_write(b, t);
382}
383
384static int bus_socket_auth_verify_server(sd_bus *b) {
385 char *e;
386 const char *line;
387 size_t l;
388 bool_Bool processed = false0;
389 int r;
390
391 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 391, __PRETTY_FUNCTION__); } while (0)
;
392
393 if (b->rbuffer_size < 1)
394 return 0;
395
396 /* First char must be a NUL byte */
397 if (*(char*) b->rbuffer != 0)
398 return -EIO5;
399
400 if (b->rbuffer_size < 3)
401 return 0;
402
403 /* Begin with the first line */
404 if (b->auth_rbegin <= 0)
405 b->auth_rbegin = 1;
406
407 for (;;) {
408 /* Check if line is complete */
409 line = (char*) b->rbuffer + b->auth_rbegin;
410 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
411 if (!e)
412 return processed;
413
414 l = e - line;
415
416 if (line_begins(line, l, "AUTH ANONYMOUS")) {
417
418 r = verify_anonymous_token(b,
419 line + strlen("AUTH ANONYMOUS"),
420 l - strlen("AUTH ANONYMOUS"));
421 if (r < 0)
422 return r;
423 if (r == 0)
424 r = bus_socket_auth_write(b, "REJECTED\r\n");
425 else {
426 b->auth = BUS_AUTH_ANONYMOUS;
427 if (l <= strlen("AUTH ANONYMOUS"))
428 r = bus_socket_auth_write(b, "DATA\r\n");
429 else
430 r = bus_socket_auth_write_ok(b);
431 }
432
433 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
434
435 r = verify_external_token(b,
436 line + strlen("AUTH EXTERNAL"),
437 l - strlen("AUTH EXTERNAL"));
438 if (r < 0)
439 return r;
440 if (r == 0)
441 r = bus_socket_auth_write(b, "REJECTED\r\n");
442 else {
443 b->auth = BUS_AUTH_EXTERNAL;
444 if (l <= strlen("AUTH EXTERNAL"))
445 r = bus_socket_auth_write(b, "DATA\r\n");
446 else
447 r = bus_socket_auth_write_ok(b);
448 }
449
450 } else if (line_begins(line, l, "AUTH"))
451 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
452 else if (line_equals(line, l, "CANCEL") ||
453 line_begins(line, l, "ERROR")) {
454
455 b->auth = _BUS_AUTH_INVALID;
456 r = bus_socket_auth_write(b, "REJECTED\r\n");
457
458 } else if (line_equals(line, l, "BEGIN")) {
459
460 if (b->auth == _BUS_AUTH_INVALID)
461 r = bus_socket_auth_write(b, "ERROR\r\n");
462 else {
463 /* We can't leave from the auth phase
464 * before we haven't written
465 * everything queued, so let's check
466 * that */
467
468 if (bus_socket_auth_needs_write(b))
469 return 1;
470
471 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
472 memmove(b->rbuffer, e + 2, b->rbuffer_size);
473 return bus_start_running(b);
474 }
475
476 } else if (line_begins(line, l, "DATA")) {
477
478 if (b->auth == _BUS_AUTH_INVALID)
479 r = bus_socket_auth_write(b, "ERROR\r\n");
480 else {
481 if (b->auth == BUS_AUTH_ANONYMOUS)
482 r = verify_anonymous_token(b, line + 4, l - 4);
483 else
484 r = verify_external_token(b, line + 4, l - 4);
485
486 if (r < 0)
487 return r;
488 if (r == 0) {
489 b->auth = _BUS_AUTH_INVALID;
490 r = bus_socket_auth_write(b, "REJECTED\r\n");
491 } else
492 r = bus_socket_auth_write_ok(b);
493 }
494 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
495 if (b->auth == _BUS_AUTH_INVALID || !b->accept_fd)
496 r = bus_socket_auth_write(b, "ERROR\r\n");
497 else {
498 b->can_fds = true1;
499 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
500 }
501 } else
502 r = bus_socket_auth_write(b, "ERROR\r\n");
503
504 if (r < 0)
505 return r;
506
507 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
508
509 processed = true1;
510 }
511}
512
513static int bus_socket_auth_verify(sd_bus *b) {
514 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 514, __PRETTY_FUNCTION__); } while (0)
;
515
516 if (b->is_server)
517 return bus_socket_auth_verify_server(b);
518 else
519 return bus_socket_auth_verify_client(b);
520}
521
522static int bus_socket_read_auth(sd_bus *b) {
523 struct msghdr mh;
524 struct iovec iov = {};
525 size_t n;
526 ssize_t k;
527 int r;
528 void *p;
529 union {
530 struct cmsghdr cmsghdr;
531 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)((((sizeof(int) * 1024) + sizeof (size_t) - 1) & (size_t)
~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
];
532 } control;
533 bool_Bool handle_cmsg = false0;
534
535 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 535, __PRETTY_FUNCTION__); } while (0)
;
536 assert(b->state == BUS_AUTHENTICATING)do { if ((__builtin_expect(!!(!(b->state == BUS_AUTHENTICATING
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->state == BUS_AUTHENTICATING"
), "../src/libsystemd/sd-bus/bus-socket.c", 536, __PRETTY_FUNCTION__
); } while (0)
;
537
538 r = bus_socket_auth_verify(b);
539 if (r != 0)
540 return r;
541
542 n = MAX(256u, b->rbuffer_size * 2)__extension__ ({ const typeof((256u)) __unique_prefix_A10 = (
(256u)); const typeof((b->rbuffer_size * 2)) __unique_prefix_B11
= ((b->rbuffer_size * 2)); __unique_prefix_A10 > __unique_prefix_B11
? __unique_prefix_A10 : __unique_prefix_B11; })
;
543
544 if (n > BUS_AUTH_SIZE_MAX(64*1024))
545 n = BUS_AUTH_SIZE_MAX(64*1024);
546
547 if (b->rbuffer_size >= n)
548 return -ENOBUFS105;
549
550 p = realloc(b->rbuffer, n);
551 if (!p)
552 return -ENOMEM12;
553
554 b->rbuffer = p;
555
556 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
557 iov.iov_len = n - b->rbuffer_size;
558
559 if (b->prefer_readv)
560 k = readv(b->input_fd, &iov, 1);
561 else {
562 zero(mh)(({ size_t _l_ = (sizeof(mh)); void *_x_ = (&(mh)); _l_ ==
0 ? _x_ : memset(_x_, 0, _l_); }))
;
563 mh.msg_iov = &iov;
564 mh.msg_iovlen = 1;
565 mh.msg_control = &control;
566 mh.msg_controllen = sizeof(control);
567
568 k = recvmsg(b->input_fd, &mh, MSG_DONTWAITMSG_DONTWAIT|MSG_CMSG_CLOEXECMSG_CMSG_CLOEXEC);
569 if (k < 0 && errno(*__errno_location ()) == ENOTSOCK88) {
570 b->prefer_readv = true1;
571 k = readv(b->input_fd, &iov, 1);
572 } else
573 handle_cmsg = true1;
574 }
575 if (k < 0)
576 return errno(*__errno_location ()) == EAGAIN11 ? 0 : -errno(*__errno_location ());
577 if (k == 0)
578 return -ECONNRESET104;
579
580 b->rbuffer_size += k;
581
582 if (handle_cmsg) {
583 struct cmsghdr *cmsg;
584
585 CMSG_FOREACH(cmsg, &mh)for ((cmsg) = ((size_t) (&mh)->msg_controllen >= sizeof
(struct cmsghdr) ? (struct cmsghdr *) (&mh)->msg_control
: (struct cmsghdr *) 0); (cmsg); (cmsg) = __cmsg_nxthdr ((&
mh), (cmsg)))
586 if (cmsg->cmsg_level == SOL_SOCKET1 &&
587 cmsg->cmsg_type == SCM_RIGHTSSCM_RIGHTS) {
588 int j;
589
590 /* Whut? We received fds during the auth
591 * protocol? Somebody is playing games with
592 * us. Close them all, and fail */
593 j = (cmsg->cmsg_len - CMSG_LEN(0)((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (0))
) / sizeof(int);
594 close_many((int*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data), j);
595 return -EIO5;
596 } else
597 log_debug("Got unexpected auxiliary data with level=%d and type=%d",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 598, __func__, "Got unexpected auxiliary data with level=%d and type=%d"
, cmsg->cmsg_level, cmsg->cmsg_type) : -abs(_e); })
598 cmsg->cmsg_level, cmsg->cmsg_type)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 598, __func__, "Got unexpected auxiliary data with level=%d and type=%d"
, cmsg->cmsg_level, cmsg->cmsg_type) : -abs(_e); })
;
599 }
600
601 r = bus_socket_auth_verify(b);
602 if (r != 0)
603 return r;
604
605 return 1;
606}
607
608void bus_socket_setup(sd_bus *b) {
609 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 609, __PRETTY_FUNCTION__); } while (0)
;
610
611 /* Increase the buffers to 8 MB */
612 (void) fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE(8*1024*1024));
613 (void) fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE(8*1024*1024));
614
615 b->message_version = 1;
616 b->message_endian = 0;
617}
618
619static void bus_get_peercred(sd_bus *b) {
620 int r;
621
622 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 622, __PRETTY_FUNCTION__); } while (0)
;
623 assert(!b->ucred_valid)do { if ((__builtin_expect(!!(!(!b->ucred_valid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!b->ucred_valid"), "../src/libsystemd/sd-bus/bus-socket.c"
, 623, __PRETTY_FUNCTION__); } while (0)
;
624 assert(!b->label)do { if ((__builtin_expect(!!(!(!b->label)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!b->label"), "../src/libsystemd/sd-bus/bus-socket.c"
, 624, __PRETTY_FUNCTION__); } while (0)
;
625 assert(b->n_groups == (size_t) -1)do { if ((__builtin_expect(!!(!(b->n_groups == (size_t) -1
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->n_groups == (size_t) -1"
), "../src/libsystemd/sd-bus/bus-socket.c", 625, __PRETTY_FUNCTION__
); } while (0)
;
626
627 /* Get the peer for socketpair() sockets */
628 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
629
630 /* Get the SELinux context of the peer */
631 r = getpeersec(b->input_fd, &b->label);
632 if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-95, -92})/sizeof(int)]; switch(r) { case
-95: case -92: _found = 1; break; default: break; } _found; }
)
)
633 log_debug_errno(r, "Failed to determine peer security context: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 633, __func__, "Failed to determine peer security context: %m"
) : -abs(_e); })
;
634
635 /* Get the list of auxiliary groups of the peer */
636 r = getpeergroups(b->input_fd, &b->groups);
637 if (r >= 0)
638 b->n_groups = (size_t) r;
639 else if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-95, -92})/sizeof(int)]; switch(r) { case
-95: case -92: _found = 1; break; default: break; } _found; }
)
)
640 log_debug_errno(r, "Failed to determine peer's group list: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 640, __func__, "Failed to determine peer's group list: %m"
) : -abs(_e); })
;
641}
642
643static int bus_socket_start_auth_client(sd_bus *b) {
644 static const char sasl_auth_anonymous[] = {
645 /*
646 * We use an arbitrary trace-string for the ANONYMOUS authentication. It can be used by the
647 * message broker to aid debugging of clients. We fully anonymize the connection and use a
648 * static default.
649 */
650 "\0AUTH ANONYMOUS\r\n"
651 /* HEX a n o n y m o u s */
652 "DATA 616e6f6e796d6f7573\r\n"
653 };
654 static const char sasl_auth_external[] = {
655 "\0AUTH EXTERNAL\r\n"
656 "DATA\r\n"
657 };
658 static const char sasl_negotiate_unix_fd[] = {
659 "NEGOTIATE_UNIX_FD\r\n"
660 };
661 static const char sasl_begin[] = {
662 "BEGIN\r\n"
663 };
664 size_t i = 0;
665
666 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 666, __PRETTY_FUNCTION__); } while (0)
;
667
668 if (b->anonymous_auth)
669 b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_anonymous, sizeof(sasl_auth_anonymous) - 1)(struct iovec) { .iov_base = ((char*) sasl_auth_anonymous), .
iov_len = (sizeof(sasl_auth_anonymous) - 1) }
;
670 else
671 b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_external, sizeof(sasl_auth_external) - 1)(struct iovec) { .iov_base = ((char*) sasl_auth_external), .iov_len
= (sizeof(sasl_auth_external) - 1) }
;
672
673 if (b->accept_fd)
674 b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_negotiate_unix_fd)(struct iovec) { .iov_base = ((char*) sasl_negotiate_unix_fd)
, .iov_len = (strlen(sasl_negotiate_unix_fd)) }
;
675
676 b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_begin)(struct iovec) { .iov_base = ((char*) sasl_begin), .iov_len =
(strlen(sasl_begin)) }
;
677
678 return bus_socket_write_auth(b);
679}
680
681int bus_socket_start_auth(sd_bus *b) {
682 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 682, __PRETTY_FUNCTION__); } while (0)
;
683
684 bus_get_peercred(b);
685
686 bus_set_state(b, BUS_AUTHENTICATING);
687 b->auth_timeout = now(CLOCK_MONOTONIC1) + BUS_AUTH_TIMEOUT((usec_t) (90*((usec_t) 1000000ULL)));
688
689 if (sd_is_socket(b->input_fd, AF_UNIX1, 0, 0) <= 0)
690 b->accept_fd = false0;
691
692 if (b->output_fd != b->input_fd)
693 if (sd_is_socket(b->output_fd, AF_UNIX1, 0, 0) <= 0)
694 b->accept_fd = false0;
695
696 if (b->is_server)
697 return bus_socket_read_auth(b);
698 else
699 return bus_socket_start_auth_client(b);
700}
701
702static int bus_socket_inotify_setup(sd_bus *b) {
703 _cleanup_free___attribute__((cleanup(freep))) int *new_watches = NULL((void*)0);
704 _cleanup_free___attribute__((cleanup(freep))) char *absolute = NULL((void*)0);
705 size_t n_allocated = 0, n = 0, done = 0, i;
706 unsigned max_follow = 32;
707 const char *p;
708 int wd, r;
709
710 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 710, __PRETTY_FUNCTION__); } while (0)
;
41
Taking false branch
42
Loop condition is false. Exiting loop
711 assert(b->watch_bind)do { if ((__builtin_expect(!!(!(b->watch_bind)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b->watch_bind"), "../src/libsystemd/sd-bus/bus-socket.c"
, 711, __PRETTY_FUNCTION__); } while (0)
;
43
Assuming field 'watch_bind' is true
44
Taking false branch
45
Loop condition is false. Exiting loop
712 assert(b->sockaddr.sa.sa_family == AF_UNIX)do { if ((__builtin_expect(!!(!(b->sockaddr.sa.sa_family ==
1)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->sockaddr.sa.sa_family == AF_UNIX"
), "../src/libsystemd/sd-bus/bus-socket.c", 712, __PRETTY_FUNCTION__
); } while (0)
;
46
Assuming field 'sa_family' is equal to 1
47
Taking false branch
48
Loop condition is false. Exiting loop
713 assert(b->sockaddr.un.sun_path[0] != 0)do { if ((__builtin_expect(!!(!(b->sockaddr.un.sun_path[0]
!= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->sockaddr.un.sun_path[0] != 0"
), "../src/libsystemd/sd-bus/bus-socket.c", 713, __PRETTY_FUNCTION__
); } while (0)
;
49
Assuming the condition is true
50
Taking false branch
51
Loop condition is false. Exiting loop
714
715 /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system socket
716 * appears before connecting to it. The implemented is pretty simplistic: we just subscribe to relevant changes
717 * to all prefix components of the path, and every time we get an event for that we try to reconnect again,
718 * without actually caring what precisely the event we got told us. If we still can't connect we re-subscribe
719 * to all relevant changes of anything in the path, so that our watches include any possibly newly created path
720 * components. */
721
722 if (b->inotify_fd < 0) {
52
Assuming field 'inotify_fd' is >= 0
53
Taking false branch
723 b->inotify_fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|IN_CLOEXECIN_CLOEXEC);
724 if (b->inotify_fd < 0)
725 return -errno(*__errno_location ());
726
727 b->inotify_fd = fd_move_above_stdio(b->inotify_fd);
728 }
729
730 /* Make sure the path is NUL terminated */
731 p = strndupa(b->sockaddr.un.sun_path, sizeof(b->sockaddr.un.sun_path))(__extension__ ({ const char *__old = (b->sockaddr.un.sun_path
); size_t __len = strnlen (__old, (sizeof(b->sockaddr.un.sun_path
))); char *__new = (char *) __builtin_alloca (__len + 1); __new
[__len] = '\0'; (char *) memcpy (__new, __old, __len); }))
;
732
733 /* Make sure the path is absolute */
734 r = path_make_absolute_cwd(p, &absolute);
735 if (r < 0)
54
Assuming 'r' is >= 0
55
Taking false branch
736 goto fail;
737
738 /* Watch all parent directories, and don't mind any prefix that doesn't exist yet. For the innermost directory
739 * that exists we want to know when files are created or moved into it. For all parents of it we just care if
740 * they are removed or renamed. */
741
742 if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)greedy_realloc((void**) &(new_watches), &(n_allocated
), (n + 1), sizeof((new_watches)[0]))
) {
56
Assuming the condition is false
57
Taking false branch
743 r = -ENOMEM12;
744 goto fail;
745 }
746
747 /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a symlink, and
748 * always exists */
749 wd = inotify_add_watch(b->inotify_fd, "/", IN_CREATE0x00000100|IN_MOVED_TO0x00000080);
750 if (wd < 0) {
58
Assuming 'wd' is >= 0
59
Taking false branch
751 r = log_debug_errno(errno, "Failed to add inotify watch on /: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-bus/bus-socket.c",
751, __func__, "Failed to add inotify watch on /: %m") : -abs
(_e); })
;
752 goto fail;
753 } else
754 new_watches[n++] = wd;
755
756 for (;;) {
60
Loop condition is true. Entering loop body
757 _cleanup_free___attribute__((cleanup(freep))) char *component = NULL((void*)0), *prefix = NULL((void*)0), *destination = NULL((void*)0);
758 size_t n_slashes, n_component;
759 char *c = NULL((void*)0);
760
761 n_slashes = strspn(absolute + done, "/");
762 n_component = n_slashes + strcspn(absolute + done + n_slashes, "/");
763
764 if (n_component == 0) /* The end */
61
Assuming 'n_component' is not equal to 0
62
Taking false branch
765 break;
766
767 component = strndup(absolute + done, n_component);
768 if (!component) {
63
Assuming 'component' is non-null
64
Taking false branch
769 r = -ENOMEM12;
770 goto fail;
771 }
772
773 /* A trailing slash? That's a directory, and not a socket then */
774 if (path_equal(component, "/")) {
65
Assuming the condition is false
66
Taking false branch
775 r = -EISDIR21;
776 goto fail;
777 }
778
779 /* A single dot? Let's eat this up */
780 if (path_equal(component, "/.")) {
67
Assuming the condition is false
68
Taking false branch
781 done += n_component;
782 continue;
783 }
784
785 prefix = strndup(absolute, done + n_component);
69
Memory is allocated
786 if (!prefix) {
70
Assuming 'prefix' is non-null
71
Taking false branch
787 r = -ENOMEM12;
788 goto fail;
789 }
790
791 if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)greedy_realloc((void**) &(new_watches), &(n_allocated
), (n + 1), sizeof((new_watches)[0]))
) {
72
Assuming the condition is true
73
Taking true branch
792 r = -ENOMEM12;
74
Potential leak of memory pointed to by 'prefix'
793 goto fail;
794 }
795
796 wd = inotify_add_watch(b->inotify_fd, prefix, IN_DELETE_SELF0x00000400|IN_MOVE_SELF0x00000800|IN_ATTRIB0x00000004|IN_CREATE0x00000100|IN_MOVED_TO0x00000080|IN_DONT_FOLLOW0x02000000);
797 log_debug("Added inotify watch for %s on bus %s: %i", prefix, strna(b->description), wd)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 797, __func__, "Added inotify watch for %s on bus %s: %i"
, prefix, strna(b->description), wd) : -abs(_e); })
;
798
799 if (wd < 0) {
800 if (IN_SET(errno, ENOENT, ELOOP)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 40})/sizeof(int)]; switch((*__errno_location
())) { case 2: case 40: _found = 1; break; default: break; }
_found; })
)
801 break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */
802
803 r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix))({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-bus/bus-socket.c",
803, __func__, "Failed to add inotify watch on %s: %m", empty_to_root
(prefix)) : -abs(_e); })
;
804 goto fail;
805 } else
806 new_watches[n++] = wd;
807
808 /* Check if this is possibly a symlink. If so, let's follow it and watch it too. */
809 r = readlink_malloc(prefix, &destination);
810 if (r == -EINVAL22) { /* not a symlink */
811 done += n_component;
812 continue;
813 }
814 if (r < 0)
815 goto fail;
816
817 if (isempty(destination)) { /* Empty symlink target? Yuck! */
818 r = -EINVAL22;
819 goto fail;
820 }
821
822 if (max_follow <= 0) { /* Let's make sure we don't follow symlinks forever */
823 r = -ELOOP40;
824 goto fail;
825 }
826
827 if (path_is_absolute(destination)) {
828 /* For absolute symlinks we build the new path and start anew */
829 c = strjoin(destination, absolute + done + n_component)strjoin_real((destination), absolute + done + n_component, ((
void*)0))
;
830 done = 0;
831 } else {
832 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
833
834 /* For relative symlinks we replace the last component, and try again */
835 t = strndup(absolute, done);
836 if (!t)
837 return -ENOMEM12;
838
839 c = strjoin(t, "/", destination, absolute + done + n_component)strjoin_real((t), "/", destination, absolute + done + n_component
, ((void*)0))
;
840 }
841 if (!c) {
842 r = -ENOMEM12;
843 goto fail;
844 }
845
846 free(absolute);
847 absolute = c;
848
849 max_follow--;
850 }
851
852 /* And now, let's remove all watches from the previous iteration we don't need anymore */
853 for (i = 0; i < b->n_inotify_watches; i++) {
854 bool_Bool found = false0;
855 size_t j;
856
857 for (j = 0; j < n; j++)
858 if (new_watches[j] == b->inotify_watches[i]) {
859 found = true1;
860 break;
861 }
862
863 if (found)
864 continue;
865
866 (void) inotify_rm_watch(b->inotify_fd, b->inotify_watches[i]);
867 }
868
869 free_and_replace(b->inotify_watches, new_watches)({ free(b->inotify_watches); (b->inotify_watches) = (new_watches
); (new_watches) = ((void*)0); 0; })
;
870 b->n_inotify_watches = n;
871
872 return 0;
873
874fail:
875 bus_close_inotify_fd(b);
876 return r;
877}
878
879int bus_socket_connect(sd_bus *b) {
880 bool_Bool inotify_done = false0;
881 int r;
882
883 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 883, __PRETTY_FUNCTION__); } while (0)
;
15
Taking false branch
16
Loop condition is false. Exiting loop
884
885 for (;;) {
17
Loop condition is true. Entering loop body
886 assert(b->input_fd < 0)do { if ((__builtin_expect(!!(!(b->input_fd < 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b->input_fd < 0"), "../src/libsystemd/sd-bus/bus-socket.c"
, 886, __PRETTY_FUNCTION__); } while (0)
;
18
Assuming field 'input_fd' is < 0
19
Taking false branch
20
Loop condition is false. Exiting loop
887 assert(b->output_fd < 0)do { if ((__builtin_expect(!!(!(b->output_fd < 0)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->output_fd < 0"
), "../src/libsystemd/sd-bus/bus-socket.c", 887, __PRETTY_FUNCTION__
); } while (0)
;
21
Assuming field 'output_fd' is < 0
22
Taking false branch
23
Loop condition is false. Exiting loop
888 assert(b->sockaddr.sa.sa_family != AF_UNSPEC)do { if ((__builtin_expect(!!(!(b->sockaddr.sa.sa_family !=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->sockaddr.sa.sa_family != AF_UNSPEC"
), "../src/libsystemd/sd-bus/bus-socket.c", 888, __PRETTY_FUNCTION__
); } while (0)
;
24
Assuming field 'sa_family' is not equal to 0
25
Taking false branch
26
Loop condition is false. Exiting loop
889
890 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAMSOCK_STREAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0);
891 if (b->input_fd < 0)
27
Assuming field 'input_fd' is >= 0
28
Taking false branch
892 return -errno(*__errno_location ());
893
894 b->input_fd = fd_move_above_stdio(b->input_fd);
895
896 b->output_fd = b->input_fd;
897 bus_socket_setup(b);
898
899 if (connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size) < 0) {
29
Assuming the condition is true
30
Taking true branch
900 if (errno(*__errno_location ()) == EINPROGRESS115) {
31
Assuming the condition is false
32
Taking false branch
901
902 /* If we have any inotify watches open, close them now, we don't need them anymore, as
903 * we have successfully initiated a connection */
904 bus_close_inotify_fd(b);
905
906 /* Note that very likely we are already in BUS_OPENING state here, as we enter it when
907 * we start parsing the address string. The only reason we set the state explicitly
908 * here, is to undo BUS_WATCH_BIND, in case we did the inotify magic. */
909 bus_set_state(b, BUS_OPENING);
910 return 1;
911 }
912
913 if (IN_SET(errno, ENOENT, ECONNREFUSED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 111})/sizeof(int)]; switch((*__errno_location
())) { case 2: case 111: _found = 1; break; default: break; }
_found; })
&& /* ENOENT → unix socket doesn't exist at all; ECONNREFUSED → unix socket stale */
33
Control jumps to 'case 111:' at line 913
34
Execution continues on line 913
38
Taking true branch
914 b->watch_bind &&
35
Assuming field 'watch_bind' is true
915 b->sockaddr.sa.sa_family == AF_UNIX1 &&
36
Assuming field 'sa_family' is equal to AF_UNIX
916 b->sockaddr.un.sun_path[0] != 0) {
37
Assuming the condition is true
917
918 /* This connection attempt failed, let's release the socket for now, and start with a
919 * fresh one when reconnecting. */
920 bus_close_io_fds(b);
921
922 if (inotify_done
38.1
'inotify_done' is false
) {
39
Taking false branch
923 /* inotify set up already, don't do it again, just return now, and remember
924 * that we are waiting for inotify events now. */
925 bus_set_state(b, BUS_WATCH_BIND);
926 return 1;
927 }
928
929 /* This is a file system socket, and the inotify logic is enabled. Let's create the necessary inotify fd. */
930 r = bus_socket_inotify_setup(b);
40
Calling 'bus_socket_inotify_setup'
931 if (r < 0)
932 return r;
933
934 /* Let's now try to connect a second time, because in theory there's otherwise a race
935 * here: the socket might have been created in the time between our first connect() and
936 * the time we set up the inotify logic. But let's remember that we set up inotify now,
937 * so that we don't do the connect() more than twice. */
938 inotify_done = true1;
939
940 } else
941 return -errno(*__errno_location ());
942 } else
943 break;
944 }
945
946 /* Yay, established, we don't need no inotify anymore! */
947 bus_close_inotify_fd(b);
948
949 return bus_socket_start_auth(b);
950}
951
952int bus_socket_exec(sd_bus *b) {
953 int s[2], r;
954
955 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 955, __PRETTY_FUNCTION__); } while (0)
;
956 assert(b->input_fd < 0)do { if ((__builtin_expect(!!(!(b->input_fd < 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b->input_fd < 0"), "../src/libsystemd/sd-bus/bus-socket.c"
, 956, __PRETTY_FUNCTION__); } while (0)
;
957 assert(b->output_fd < 0)do { if ((__builtin_expect(!!(!(b->output_fd < 0)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->output_fd < 0"
), "../src/libsystemd/sd-bus/bus-socket.c", 957, __PRETTY_FUNCTION__
); } while (0)
;
958 assert(b->exec_path)do { if ((__builtin_expect(!!(!(b->exec_path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b->exec_path"), "../src/libsystemd/sd-bus/bus-socket.c"
, 958, __PRETTY_FUNCTION__); } while (0)
;
959 assert(b->busexec_pid == 0)do { if ((__builtin_expect(!!(!(b->busexec_pid == 0)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->busexec_pid == 0"
), "../src/libsystemd/sd-bus/bus-socket.c", 959, __PRETTY_FUNCTION__
); } while (0)
;
960
961 r = socketpair(AF_UNIX1, SOCK_STREAMSOCK_STREAM|SOCK_NONBLOCKSOCK_NONBLOCK|SOCK_CLOEXECSOCK_CLOEXEC, 0, s);
962 if (r < 0)
963 return -errno(*__errno_location ());
964
965 r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &b->busexec_pid);
966 if (r < 0) {
967 safe_close_pair(s);
968 return r;
969 }
970 if (r == 0) {
971 /* Child */
972
973 if (rearrange_stdio(s[1], s[1], STDERR_FILENO2) < 0)
974 _exit(EXIT_FAILURE1);
975
976 if (b->exec_argv)
977 execvp(b->exec_path, b->exec_argv);
978 else {
979 const char *argv[] = { b->exec_path, NULL((void*)0) };
980 execvp(b->exec_path, (char**) argv);
981 }
982
983 _exit(EXIT_FAILURE1);
984 }
985
986 safe_close(s[1]);
987 b->output_fd = b->input_fd = fd_move_above_stdio(s[0]);
988
989 bus_socket_setup(b);
990
991 return bus_socket_start_auth(b);
992}
993
994int bus_socket_take_fd(sd_bus *b) {
995 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 995, __PRETTY_FUNCTION__); } while (0)
;
996
997 bus_socket_setup(b);
998
999 return bus_socket_start_auth(b);
1000}
1001
1002int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
1003 struct iovec *iov;
1004 ssize_t k;
1005 size_t n;
1006 unsigned j;
1007 int r;
1008
1009 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1009, __PRETTY_FUNCTION__); } while (0)
;
1010 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1010, __PRETTY_FUNCTION__); } while (0)
;
1011 assert(idx)do { if ((__builtin_expect(!!(!(idx)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("idx"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1011, __PRETTY_FUNCTION__); } while (0)
;
1012 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){BUS_RUNNING, BUS_HELLO})/sizeof(int)]; switch
(bus->state) { case BUS_RUNNING: case BUS_HELLO: _found = 1
; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)"
), "../src/libsystemd/sd-bus/bus-socket.c", 1012, __PRETTY_FUNCTION__
); } while (0)
;
1013
1014 if (*idx >= BUS_MESSAGE_SIZE(m))
1015 return 0;
1016
1017 r = bus_message_setup_iovec(m);
1018 if (r < 0)
1019 return r;
1020
1021 n = m->n_iovec * sizeof(struct iovec);
1022 iov = alloca(n)__builtin_alloca (n);
1023 memcpy_safe(iov, m->iovec, n);
1024
1025 j = 0;
1026 iovec_advance(iov, &j, *idx);
1027
1028 if (bus->prefer_writev)
1029 k = writev(bus->output_fd, iov, m->n_iovec);
1030 else {
1031 struct msghdr mh = {
1032 .msg_iov = iov,
1033 .msg_iovlen = m->n_iovec,
1034 };
1035
1036 if (m->n_fds > 0 && *idx == 0) {
1037 struct cmsghdr *control;
1038
1039 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds))__builtin_alloca (((((sizeof(int) * m->n_fds) + sizeof (size_t
) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct
cmsghdr)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t
) - 1))))
;
1040 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds)((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(int) * m->n_fds))
;
1041 control->cmsg_level = SOL_SOCKET1;
1042 control->cmsg_type = SCM_RIGHTSSCM_RIGHTS;
1043 memcpy(CMSG_DATA(control)((control)->__cmsg_data), m->fds, sizeof(int) * m->n_fds);
1044 }
1045
1046 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAITMSG_DONTWAIT|MSG_NOSIGNALMSG_NOSIGNAL);
1047 if (k < 0 && errno(*__errno_location ()) == ENOTSOCK88) {
1048 bus->prefer_writev = true1;
1049 k = writev(bus->output_fd, iov, m->n_iovec);
1050 }
1051 }
1052
1053 if (k < 0)
1054 return errno(*__errno_location ()) == EAGAIN11 ? 0 : -errno(*__errno_location ());
1055
1056 *idx += (size_t) k;
1057 return 1;
1058}
1059
1060static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
1061 uint32_t a, b;
1062 uint8_t e;
1063 uint64_t sum;
1064
1065 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1065, __PRETTY_FUNCTION__); } while (0)
;
1066 assert(need)do { if ((__builtin_expect(!!(!(need)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("need"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1066, __PRETTY_FUNCTION__); } while (0)
;
1067 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){BUS_RUNNING, BUS_HELLO})/sizeof(int)]; switch
(bus->state) { case BUS_RUNNING: case BUS_HELLO: _found = 1
; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)"
), "../src/libsystemd/sd-bus/bus-socket.c", 1067, __PRETTY_FUNCTION__
); } while (0)
;
1068
1069 if (bus->rbuffer_size < sizeof(struct bus_header)) {
1070 *need = sizeof(struct bus_header) + 8;
1071
1072 /* Minimum message size:
1073 *
1074 * Header +
1075 *
1076 * Method Call: +2 string headers
1077 * Signal: +3 string headers
1078 * Method Error: +1 string headers
1079 * +1 uint32 headers
1080 * Method Reply: +1 uint32 headers
1081 *
1082 * A string header is at least 9 bytes
1083 * A uint32 header is at least 8 bytes
1084 *
1085 * Hence the minimum message size of a valid message
1086 * is header + 8 bytes */
1087
1088 return 0;
1089 }
1090
1091 a = ((const uint32_t*) bus->rbuffer)[1];
1092 b = ((const uint32_t*) bus->rbuffer)[3];
1093
1094 e = ((const uint8_t*) bus->rbuffer)[0];
1095 if (e == BUS_LITTLE_ENDIAN) {
1096 a = le32toh(a)__uint32_identity (a);
1097 b = le32toh(b)__uint32_identity (b);
1098 } else if (e == BUS_BIG_ENDIAN) {
1099 a = be32toh(a)__bswap_32 (a);
1100 b = be32toh(b)__bswap_32 (b);
1101 } else
1102 return -EBADMSG74;
1103
1104 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
1105 if (sum >= BUS_MESSAGE_SIZE_MAX(128*1024*1024))
1106 return -ENOBUFS105;
1107
1108 *need = (size_t) sum;
1109 return 0;
1110}
1111
1112static int bus_socket_make_message(sd_bus *bus, size_t size) {
1113 sd_bus_message *t = NULL((void*)0);
1114 void *b;
1115 int r;
1116
1117 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1117, __PRETTY_FUNCTION__); } while (0)
;
1118 assert(bus->rbuffer_size >= size)do { if ((__builtin_expect(!!(!(bus->rbuffer_size >= size
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("bus->rbuffer_size >= size"
), "../src/libsystemd/sd-bus/bus-socket.c", 1118, __PRETTY_FUNCTION__
); } while (0)
;
1119 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){BUS_RUNNING, BUS_HELLO})/sizeof(int)]; switch
(bus->state) { case BUS_RUNNING: case BUS_HELLO: _found = 1
; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)"
), "../src/libsystemd/sd-bus/bus-socket.c", 1119, __PRETTY_FUNCTION__
); } while (0)
;
1120
1121 r = bus_rqueue_make_room(bus);
1122 if (r < 0)
1123 return r;
1124
1125 if (bus->rbuffer_size > size) {
1126 b = memdup((const uint8_t*) bus->rbuffer + size,
1127 bus->rbuffer_size - size);
1128 if (!b)
1129 return -ENOMEM12;
1130 } else
1131 b = NULL((void*)0);
1132
1133 r = bus_message_from_malloc(bus,
1134 bus->rbuffer, size,
1135 bus->fds, bus->n_fds,
1136 NULL((void*)0),
1137 &t);
1138 if (r == -EBADMSG74)
1139 log_debug_errno(r, "Received invalid message from connection %s, dropping.", strna(bus->description))({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 1139, __func__, "Received invalid message from connection %s, dropping."
, strna(bus->description)) : -abs(_e); })
;
1140 else if (r < 0) {
1141 free(b);
1142 return r;
1143 }
1144
1145 bus->rbuffer = b;
1146 bus->rbuffer_size -= size;
1147
1148 bus->fds = NULL((void*)0);
1149 bus->n_fds = 0;
1150
1151 if (t) {
1152 bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(t, bus);
1153 sd_bus_message_unref(t);
1154 }
1155
1156 return 1;
1157}
1158
1159int bus_socket_read_message(sd_bus *bus) {
1160 struct msghdr mh;
1161 struct iovec iov = {};
1162 ssize_t k;
1163 size_t need;
1164 int r;
1165 void *b;
1166 union {
1167 struct cmsghdr cmsghdr;
1168 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)((((sizeof(int) * 1024) + sizeof (size_t) - 1) & (size_t)
~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
];
1169 } control;
1170 bool_Bool handle_cmsg = false0;
1171
1172 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1172, __PRETTY_FUNCTION__); } while (0)
;
1173 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){BUS_RUNNING, BUS_HELLO})/sizeof(int)]; switch
(bus->state) { case BUS_RUNNING: case BUS_HELLO: _found = 1
; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)"
), "../src/libsystemd/sd-bus/bus-socket.c", 1173, __PRETTY_FUNCTION__
); } while (0)
;
1174
1175 r = bus_socket_read_message_need(bus, &need);
1176 if (r < 0)
1177 return r;
1178
1179 if (bus->rbuffer_size >= need)
1180 return bus_socket_make_message(bus, need);
1181
1182 b = realloc(bus->rbuffer, need);
1183 if (!b)
1184 return -ENOMEM12;
1185
1186 bus->rbuffer = b;
1187
1188 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
1189 iov.iov_len = need - bus->rbuffer_size;
1190
1191 if (bus->prefer_readv)
1192 k = readv(bus->input_fd, &iov, 1);
1193 else {
1194 zero(mh)(({ size_t _l_ = (sizeof(mh)); void *_x_ = (&(mh)); _l_ ==
0 ? _x_ : memset(_x_, 0, _l_); }))
;
1195 mh.msg_iov = &iov;
1196 mh.msg_iovlen = 1;
1197 mh.msg_control = &control;
1198 mh.msg_controllen = sizeof(control);
1199
1200 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAITMSG_DONTWAIT|MSG_CMSG_CLOEXECMSG_CMSG_CLOEXEC);
1201 if (k < 0 && errno(*__errno_location ()) == ENOTSOCK88) {
1202 bus->prefer_readv = true1;
1203 k = readv(bus->input_fd, &iov, 1);
1204 } else
1205 handle_cmsg = true1;
1206 }
1207 if (k < 0)
1208 return errno(*__errno_location ()) == EAGAIN11 ? 0 : -errno(*__errno_location ());
1209 if (k == 0)
1210 return -ECONNRESET104;
1211
1212 bus->rbuffer_size += k;
1213
1214 if (handle_cmsg) {
1215 struct cmsghdr *cmsg;
1216
1217 CMSG_FOREACH(cmsg, &mh)for ((cmsg) = ((size_t) (&mh)->msg_controllen >= sizeof
(struct cmsghdr) ? (struct cmsghdr *) (&mh)->msg_control
: (struct cmsghdr *) 0); (cmsg); (cmsg) = __cmsg_nxthdr ((&
mh), (cmsg)))
1218 if (cmsg->cmsg_level == SOL_SOCKET1 &&
1219 cmsg->cmsg_type == SCM_RIGHTSSCM_RIGHTS) {
1220 int n, *f, i;
1221
1222 n = (cmsg->cmsg_len - CMSG_LEN(0)((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (0))
) / sizeof(int);
1223
1224 if (!bus->can_fds) {
1225 /* Whut? We received fds but this
1226 * isn't actually enabled? Close them,
1227 * and fail */
1228
1229 close_many((int*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data), n);
1230 return -EIO5;
1231 }
1232
1233 f = reallocarray(bus->fds, bus->n_fds + n, sizeof(int));
1234 if (!f) {
1235 close_many((int*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data), n);
1236 return -ENOMEM12;
1237 }
1238
1239 for (i = 0; i < n; i++)
1240 f[bus->n_fds++] = fd_move_above_stdio(((int*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data))[i]);
1241 bus->fds = f;
1242 } else
1243 log_debug("Got unexpected auxiliary data with level=%d and type=%d",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 1244, __func__, "Got unexpected auxiliary data with level=%d and type=%d"
, cmsg->cmsg_level, cmsg->cmsg_type) : -abs(_e); })
1244 cmsg->cmsg_level, cmsg->cmsg_type)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 1244, __func__, "Got unexpected auxiliary data with level=%d and type=%d"
, cmsg->cmsg_level, cmsg->cmsg_type) : -abs(_e); })
;
1245 }
1246
1247 r = bus_socket_read_message_need(bus, &need);
1248 if (r < 0)
1249 return r;
1250
1251 if (bus->rbuffer_size >= need)
1252 return bus_socket_make_message(bus, need);
1253
1254 return 1;
1255}
1256
1257int bus_socket_process_opening(sd_bus *b) {
1258 int error = 0;
1259 socklen_t slen = sizeof(error);
1260 struct pollfd p = {
1261 .fd = b->output_fd,
1262 .events = POLLOUT0x004,
1263 };
1264 int r;
1265
1266 assert(b->state == BUS_OPENING)do { if ((__builtin_expect(!!(!(b->state == BUS_OPENING)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->state == BUS_OPENING"
), "../src/libsystemd/sd-bus/bus-socket.c", 1266, __PRETTY_FUNCTION__
); } while (0)
;
1267
1268 r = poll(&p, 1, 0);
1269 if (r < 0)
1270 return -errno(*__errno_location ());
1271
1272 if (!(p.revents & (POLLOUT0x004|POLLERR0x008|POLLHUP0x010)))
1273 return 0;
1274
1275 r = getsockopt(b->output_fd, SOL_SOCKET1, SO_ERROR4, &error, &slen);
1276 if (r < 0)
1277 b->last_connect_error = errno(*__errno_location ());
1278 else if (error != 0)
1279 b->last_connect_error = error;
1280 else if (p.revents & (POLLERR0x008|POLLHUP0x010))
1281 b->last_connect_error = ECONNREFUSED111;
1282 else
1283 return bus_socket_start_auth(b);
1284
1285 return bus_next_address(b);
1286}
1287
1288int bus_socket_process_authenticating(sd_bus *b) {
1289 int r;
1290
1291 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1291, __PRETTY_FUNCTION__); } while (0)
;
1292 assert(b->state == BUS_AUTHENTICATING)do { if ((__builtin_expect(!!(!(b->state == BUS_AUTHENTICATING
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->state == BUS_AUTHENTICATING"
), "../src/libsystemd/sd-bus/bus-socket.c", 1292, __PRETTY_FUNCTION__
); } while (0)
;
1293
1294 if (now(CLOCK_MONOTONIC1) >= b->auth_timeout)
1295 return -ETIMEDOUT110;
1296
1297 r = bus_socket_write_auth(b);
1298 if (r != 0)
1299 return r;
1300
1301 return bus_socket_read_auth(b);
1302}
1303
1304int bus_socket_process_watch_bind(sd_bus *b) {
1305 int r, q;
1306
1307 assert(b)do { if ((__builtin_expect(!!(!(b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("b"), "../src/libsystemd/sd-bus/bus-socket.c"
, 1307, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'b' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
1308 assert(b->state == BUS_WATCH_BIND)do { if ((__builtin_expect(!!(!(b->state == BUS_WATCH_BIND
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->state == BUS_WATCH_BIND"
), "../src/libsystemd/sd-bus/bus-socket.c", 1308, __PRETTY_FUNCTION__
); } while (0)
;
4
Assuming field 'state' is equal to BUS_WATCH_BIND
5
Taking false branch
6
Loop condition is false. Exiting loop
1309 assert(b->inotify_fd >= 0)do { if ((__builtin_expect(!!(!(b->inotify_fd >= 0)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("b->inotify_fd >= 0"
), "../src/libsystemd/sd-bus/bus-socket.c", 1309, __PRETTY_FUNCTION__
); } while (0)
;
7
Assuming field 'inotify_fd' is >= 0
8
Taking false branch
9
Loop condition is false. Exiting loop
1310
1311 r = flush_fd(b->inotify_fd);
1312 if (r <= 0)
10
Assuming 'r' is > 0
11
Taking false branch
1313 return r;
1314
1315 log_debug("Got inotify event on bus %s.", strna(b->description))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-bus/bus-socket.c", 1315, __func__, "Got inotify event on bus %s."
, strna(b->description)) : -abs(_e); })
;
12
Assuming the condition is false
13
'?' condition is false
1316
1317 /* We flushed events out of the inotify fd. In that case, maybe the socket is valid now? Let's try to connect
1318 * to it again */
1319
1320 r = bus_socket_connect(b);
14
Calling 'bus_socket_connect'
1321 if (r < 0)
1322 return r;
1323
1324 q = bus_attach_io_events(b);
1325 if (q < 0)
1326 return q;
1327
1328 q = bus_attach_inotify_event(b);
1329 if (q < 0)
1330 return q;
1331
1332 return r;
1333}