1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <linux/filter.h>
5 #include <linux/netlink.h>
6 #include <linux/sockios.h>
7 #include <sys/ioctl.h>
8 #include <unistd.h>
9
10 #include "sd-device.h"
11 #include "sd-event.h"
12
13 #include "MurmurHash2.h"
14 #include "alloc-util.h"
15 #include "device-monitor-private.h"
16 #include "device-private.h"
17 #include "device-util.h"
18 #include "errno-util.h"
19 #include "fd-util.h"
20 #include "format-util.h"
21 #include "hashmap.h"
22 #include "io-util.h"
23 #include "missing_socket.h"
24 #include "mountpoint-util.h"
25 #include "set.h"
26 #include "socket-util.h"
27 #include "stat-util.h"
28 #include "string-util.h"
29 #include "strv.h"
30
31 struct sd_device_monitor {
32 unsigned n_ref;
33
34 int sock;
35 union sockaddr_union snl;
36 union sockaddr_union snl_trusted_sender;
37 bool bound;
38
39 Hashmap *subsystem_filter;
40 Set *tag_filter;
41 Hashmap *match_sysattr_filter;
42 Hashmap *nomatch_sysattr_filter;
43 Set *match_parent_filter;
44 Set *nomatch_parent_filter;
45 bool filter_uptodate;
46
47 sd_event *event;
48 sd_event_source *event_source;
49 sd_device_monitor_handler_t callback;
50 void *userdata;
51 };
52
53 #define UDEV_MONITOR_MAGIC 0xfeedcafe
54
55 typedef struct monitor_netlink_header {
56 /* "libudev" prefix to distinguish libudev and kernel messages */
57 char prefix[8];
58 /* Magic to protect against daemon <-> Library message format mismatch
59 * Used in the kernel from socket filter rules; needs to be stored in network order */
60 unsigned magic;
61 /* Total length of header structure known to the sender */
62 unsigned header_size;
63 /* Properties string buffer */
64 unsigned properties_off;
65 unsigned properties_len;
66 /* Hashes of primary device properties strings, to let libudev subscribers
67 * use in-kernel socket filters; values need to be stored in network order */
68 unsigned filter_subsystem_hash;
69 unsigned filter_devtype_hash;
70 unsigned filter_tag_bloom_hi;
71 unsigned filter_tag_bloom_lo;
72 } monitor_netlink_header;
73
monitor_set_nl_address(sd_device_monitor * m)74 static int monitor_set_nl_address(sd_device_monitor *m) {
75 union sockaddr_union snl;
76 socklen_t addrlen;
77
78 assert(m);
79
80 /* Get the address the kernel has assigned us.
81 * It is usually, but not necessarily the pid. */
82 addrlen = sizeof(struct sockaddr_nl);
83 if (getsockname(m->sock, &snl.sa, &addrlen) < 0)
84 return -errno;
85
86 m->snl.nl.nl_pid = snl.nl.nl_pid;
87 return 0;
88 }
89
device_monitor_allow_unicast_sender(sd_device_monitor * m,sd_device_monitor * sender)90 int device_monitor_allow_unicast_sender(sd_device_monitor *m, sd_device_monitor *sender) {
91 assert(m);
92 assert(sender);
93
94 m->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
95 return 0;
96 }
97
sd_device_monitor_set_receive_buffer_size(sd_device_monitor * m,size_t size)98 _public_ int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, size_t size) {
99 assert_return(m, -EINVAL);
100
101 return fd_set_rcvbuf(m->sock, size, false);
102 }
103
device_monitor_disconnect(sd_device_monitor * m)104 int device_monitor_disconnect(sd_device_monitor *m) {
105 assert(m);
106
107 m->sock = safe_close(m->sock);
108 return 0;
109 }
110
device_monitor_get_fd(sd_device_monitor * m)111 int device_monitor_get_fd(sd_device_monitor *m) {
112 assert(m);
113
114 return m->sock;
115 }
116
device_monitor_new_full(sd_device_monitor ** ret,MonitorNetlinkGroup group,int fd)117 int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group, int fd) {
118 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
119 _cleanup_close_ int sock = -1;
120 int r;
121
122 assert(group >= 0 && group < _MONITOR_NETLINK_GROUP_MAX);
123 assert_return(ret, -EINVAL);
124
125 if (group == MONITOR_GROUP_UDEV &&
126 access("/run/udev/control", F_OK) < 0 &&
127 dev_is_devtmpfs() <= 0) {
128
129 /*
130 * We do not support subscribing to uevents if no instance of
131 * udev is running. Uevents would otherwise broadcast the
132 * processing data of the host into containers, which is not
133 * desired.
134 *
135 * Containers will currently not get any udev uevents, until
136 * a supporting infrastructure is available.
137 *
138 * We do not set a netlink multicast group here, so the socket
139 * will not receive any messages.
140 */
141
142 log_debug("sd-device-monitor: The udev service seems not to be active, disabling the monitor");
143 group = MONITOR_GROUP_NONE;
144 }
145
146 if (fd < 0) {
147 sock = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
148 if (sock < 0)
149 return log_debug_errno(errno, "sd-device-monitor: Failed to create socket: %m");
150 }
151
152 m = new(sd_device_monitor, 1);
153 if (!m)
154 return -ENOMEM;
155
156 *m = (sd_device_monitor) {
157 .n_ref = 1,
158 .sock = fd >= 0 ? fd : TAKE_FD(sock),
159 .bound = fd >= 0,
160 .snl.nl.nl_family = AF_NETLINK,
161 .snl.nl.nl_groups = group,
162 };
163
164 if (fd >= 0) {
165 r = monitor_set_nl_address(m);
166 if (r < 0) {
167 log_debug_errno(r, "sd-device-monitor: Failed to set netlink address: %m");
168 goto fail;
169 }
170 }
171
172 if (DEBUG_LOGGING) {
173 _cleanup_close_ int netns = -1;
174
175 /* So here's the thing: only AF_NETLINK sockets from the main network namespace will get
176 * hardware events. Let's check if ours is from there, and if not generate a debug message,
177 * since we cannot possibly work correctly otherwise. This is just a safety check to make
178 * things easier to debug. */
179
180 netns = ioctl(m->sock, SIOCGSKNS);
181 if (netns < 0)
182 log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: %m");
183 else {
184 struct stat a, b;
185
186 if (fstat(netns, &a) < 0) {
187 r = log_debug_errno(errno, "sd-device-monitor: Failed to stat netns of udev netlink socket: %m");
188 goto fail;
189 }
190
191 if (stat("/proc/1/ns/net", &b) < 0) {
192 if (ERRNO_IS_PRIVILEGE(errno))
193 /* If we can't access PID1's netns info due to permissions, it's fine, this is a
194 * safety check only after all. */
195 log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns, ignoring: %m");
196 else
197 log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns, ignoring: %m");
198
199 } else if (!stat_inode_same(&a, &b))
200 log_debug("sd-device-monitor: Netlink socket we listen on is not from host netns, we won't see device events.");
201 }
202 }
203
204 *ret = TAKE_PTR(m);
205 return 0;
206
207 fail:
208 /* Let's unset the socket fd in the monitor object before we destroy it so that the fd passed in is
209 * not closed on failure. */
210 if (fd >= 0)
211 m->sock = -1;
212
213 return r;
214 }
215
sd_device_monitor_new(sd_device_monitor ** ret)216 _public_ int sd_device_monitor_new(sd_device_monitor **ret) {
217 return device_monitor_new_full(ret, MONITOR_GROUP_UDEV, -1);
218 }
219
sd_device_monitor_stop(sd_device_monitor * m)220 _public_ int sd_device_monitor_stop(sd_device_monitor *m) {
221 assert_return(m, -EINVAL);
222
223 m->event_source = sd_event_source_unref(m->event_source);
224 (void) device_monitor_disconnect(m);
225
226 return 0;
227 }
228
device_monitor_event_handler(sd_event_source * s,int fd,uint32_t revents,void * userdata)229 static int device_monitor_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
230 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
231 sd_device_monitor *m = userdata;
232
233 assert(m);
234
235 if (device_monitor_receive_device(m, &device) <= 0)
236 return 0;
237
238 if (m->callback)
239 return m->callback(m, device, m->userdata);
240
241 return 0;
242 }
243
sd_device_monitor_start(sd_device_monitor * m,sd_device_monitor_handler_t callback,void * userdata)244 _public_ int sd_device_monitor_start(sd_device_monitor *m, sd_device_monitor_handler_t callback, void *userdata) {
245 int r;
246
247 assert_return(m, -EINVAL);
248
249 if (!m->event) {
250 r = sd_device_monitor_attach_event(m, NULL);
251 if (r < 0)
252 return r;
253 }
254
255 r = device_monitor_enable_receiving(m);
256 if (r < 0)
257 return r;
258
259 m->callback = callback;
260 m->userdata = userdata;
261
262 r = sd_event_add_io(m->event, &m->event_source, m->sock, EPOLLIN, device_monitor_event_handler, m);
263 if (r < 0)
264 return r;
265
266 (void) sd_event_source_set_description(m->event_source, "sd-device-monitor");
267
268 return 0;
269 }
270
sd_device_monitor_detach_event(sd_device_monitor * m)271 _public_ int sd_device_monitor_detach_event(sd_device_monitor *m) {
272 assert_return(m, -EINVAL);
273
274 (void) sd_device_monitor_stop(m);
275 m->event = sd_event_unref(m->event);
276
277 return 0;
278 }
279
sd_device_monitor_attach_event(sd_device_monitor * m,sd_event * event)280 _public_ int sd_device_monitor_attach_event(sd_device_monitor *m, sd_event *event) {
281 int r;
282
283 assert_return(m, -EINVAL);
284 assert_return(!m->event, -EBUSY);
285
286 if (event)
287 m->event = sd_event_ref(event);
288 else {
289 r = sd_event_default(&m->event);
290 if (r < 0)
291 return r;
292 }
293
294 return 0;
295 }
296
sd_device_monitor_get_event(sd_device_monitor * m)297 _public_ sd_event *sd_device_monitor_get_event(sd_device_monitor *m) {
298 assert_return(m, NULL);
299
300 return m->event;
301 }
302
sd_device_monitor_get_event_source(sd_device_monitor * m)303 _public_ sd_event_source *sd_device_monitor_get_event_source(sd_device_monitor *m) {
304 assert_return(m, NULL);
305
306 return m->event_source;
307 }
308
device_monitor_enable_receiving(sd_device_monitor * m)309 int device_monitor_enable_receiving(sd_device_monitor *m) {
310 int r;
311
312 assert(m);
313
314 r = sd_device_monitor_filter_update(m);
315 if (r < 0)
316 return log_debug_errno(r, "sd-device-monitor: Failed to update filter: %m");
317
318 if (!m->bound) {
319 /* enable receiving of sender credentials */
320 r = setsockopt_int(m->sock, SOL_SOCKET, SO_PASSCRED, true);
321 if (r < 0)
322 return log_debug_errno(r, "sd-device-monitor: Failed to set socket option SO_PASSCRED: %m");
323
324 if (bind(m->sock, &m->snl.sa, sizeof(struct sockaddr_nl)) < 0)
325 return log_debug_errno(errno, "sd-device-monitor: Failed to bind monitoring socket: %m");
326
327 m->bound = true;
328
329 r = monitor_set_nl_address(m);
330 if (r < 0)
331 return log_debug_errno(r, "sd-device-monitor: Failed to set address: %m");
332 }
333
334 return 0;
335 }
336
device_monitor_free(sd_device_monitor * m)337 static sd_device_monitor *device_monitor_free(sd_device_monitor *m) {
338 assert(m);
339
340 (void) sd_device_monitor_detach_event(m);
341
342 hashmap_free(m->subsystem_filter);
343 set_free(m->tag_filter);
344 hashmap_free(m->match_sysattr_filter);
345 hashmap_free(m->nomatch_sysattr_filter);
346 set_free(m->match_parent_filter);
347 set_free(m->nomatch_parent_filter);
348
349 return mfree(m);
350 }
351
352 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_monitor, sd_device_monitor, device_monitor_free);
353
check_subsystem_filter(sd_device_monitor * m,sd_device * device)354 static int check_subsystem_filter(sd_device_monitor *m, sd_device *device) {
355 const char *s, *subsystem, *d, *devtype = NULL;
356 int r;
357
358 assert(m);
359 assert(device);
360
361 if (hashmap_isempty(m->subsystem_filter))
362 return true;
363
364 r = sd_device_get_subsystem(device, &subsystem);
365 if (r < 0)
366 return r;
367
368 r = sd_device_get_devtype(device, &devtype);
369 if (r < 0 && r != -ENOENT)
370 return r;
371
372 HASHMAP_FOREACH_KEY(d, s, m->subsystem_filter) {
373 if (!streq(s, subsystem))
374 continue;
375
376 if (!d || streq_ptr(d, devtype))
377 return true;
378 }
379
380 return false;
381 }
382
check_tag_filter(sd_device_monitor * m,sd_device * device)383 static bool check_tag_filter(sd_device_monitor *m, sd_device *device) {
384 const char *tag;
385
386 assert(m);
387 assert(device);
388
389 if (set_isempty(m->tag_filter))
390 return true;
391
392 SET_FOREACH(tag, m->tag_filter)
393 if (sd_device_has_tag(device, tag) > 0)
394 return true;
395
396 return false;
397 }
398
passes_filter(sd_device_monitor * m,sd_device * device)399 static int passes_filter(sd_device_monitor *m, sd_device *device) {
400 int r;
401
402 assert(m);
403 assert(device);
404
405 r = check_subsystem_filter(m, device);
406 if (r <= 0)
407 return r;
408
409 if (!check_tag_filter(m, device))
410 return false;
411
412 if (!device_match_sysattr(device, m->match_sysattr_filter, m->nomatch_sysattr_filter))
413 return false;
414
415 return device_match_parent(device, m->match_parent_filter, m->nomatch_parent_filter);
416 }
417
device_monitor_receive_device(sd_device_monitor * m,sd_device ** ret)418 int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
419 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
420 union {
421 monitor_netlink_header nlh;
422 char raw[8192];
423 } buf;
424 struct iovec iov = {
425 .iov_base = &buf,
426 .iov_len = sizeof(buf)
427 };
428 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
429 union sockaddr_union snl;
430 struct msghdr smsg = {
431 .msg_iov = &iov,
432 .msg_iovlen = 1,
433 .msg_control = &control,
434 .msg_controllen = sizeof(control),
435 .msg_name = &snl,
436 .msg_namelen = sizeof(snl),
437 };
438 struct cmsghdr *cmsg;
439 struct ucred *cred;
440 ssize_t buflen, bufpos;
441 bool is_initialized = false;
442 int r;
443
444 assert(m);
445 assert(ret);
446
447 buflen = recvmsg(m->sock, &smsg, 0);
448 if (buflen < 0) {
449 if (ERRNO_IS_TRANSIENT(errno))
450 log_debug_errno(errno, "sd-device-monitor: Failed to receive message: %m");
451 return -errno;
452 }
453
454 if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC))
455 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
456 "sd-device-monitor: Invalid message length.");
457
458 if (snl.nl.nl_groups == MONITOR_GROUP_NONE) {
459 /* unicast message, check if we trust the sender */
460 if (m->snl_trusted_sender.nl.nl_pid == 0 ||
461 snl.nl.nl_pid != m->snl_trusted_sender.nl.nl_pid)
462 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
463 "sd-device-monitor: Unicast netlink message ignored.");
464
465 } else if (snl.nl.nl_groups == MONITOR_GROUP_KERNEL) {
466 if (snl.nl.nl_pid > 0)
467 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
468 "sd-device-monitor: Multicast kernel netlink message from PID %"PRIu32" ignored.", snl.nl.nl_pid);
469 }
470
471 cmsg = CMSG_FIRSTHDR(&smsg);
472 if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS)
473 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
474 "sd-device-monitor: No sender credentials received, message ignored.");
475
476 cred = (struct ucred*) CMSG_DATA(cmsg);
477 if (cred->uid != 0)
478 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
479 "sd-device-monitor: Sender uid="UID_FMT", message ignored.", cred->uid);
480
481 if (streq(buf.raw, "libudev")) {
482 /* udev message needs proper version magic */
483 if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC))
484 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
485 "sd-device-monitor: Invalid message signature (%x != %x)",
486 buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC));
487
488 if (buf.nlh.properties_off+32 > (size_t) buflen)
489 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
490 "sd-device-monitor: Invalid message length (%u > %zd)",
491 buf.nlh.properties_off+32, buflen);
492
493 bufpos = buf.nlh.properties_off;
494
495 /* devices received from udev are always initialized */
496 is_initialized = true;
497
498 } else {
499 /* kernel message with header */
500 bufpos = strlen(buf.raw) + 1;
501 if ((size_t) bufpos < sizeof("a@/d") || bufpos >= buflen)
502 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
503 "sd-device-monitor: Invalid message length");
504
505 /* check message header */
506 if (!strstr(buf.raw, "@/"))
507 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
508 "sd-device-monitor: Invalid message header");
509 }
510
511 r = device_new_from_nulstr(&device, (uint8_t*) &buf.raw[bufpos], buflen - bufpos);
512 if (r < 0)
513 return log_debug_errno(r, "sd-device-monitor: Failed to create device from received message: %m");
514
515 if (is_initialized)
516 device_set_is_initialized(device);
517
518 /* Skip device, if it does not pass the current filter */
519 r = passes_filter(m, device);
520 if (r < 0)
521 return log_device_debug_errno(device, r, "sd-device-monitor: Failed to check received device passing filter: %m");
522 if (r == 0)
523 log_device_debug(device, "sd-device-monitor: Received device does not pass filter, ignoring");
524 else
525 *ret = TAKE_PTR(device);
526
527 return r;
528 }
529
string_hash32(const char * str)530 static uint32_t string_hash32(const char *str) {
531 return MurmurHash2(str, strlen(str), 0);
532 }
533
534 /* Get a bunch of bit numbers out of the hash, and set the bits in our bit field */
string_bloom64(const char * str)535 static uint64_t string_bloom64(const char *str) {
536 uint64_t bits = 0;
537 uint32_t hash = string_hash32(str);
538
539 bits |= UINT64_C(1) << (hash & 63);
540 bits |= UINT64_C(1) << ((hash >> 6) & 63);
541 bits |= UINT64_C(1) << ((hash >> 12) & 63);
542 bits |= UINT64_C(1) << ((hash >> 18) & 63);
543 return bits;
544 }
545
device_monitor_send_device(sd_device_monitor * m,sd_device_monitor * destination,sd_device * device)546 int device_monitor_send_device(
547 sd_device_monitor *m,
548 sd_device_monitor *destination,
549 sd_device *device) {
550
551 monitor_netlink_header nlh = {
552 .prefix = "libudev",
553 .magic = htobe32(UDEV_MONITOR_MAGIC),
554 .header_size = sizeof nlh,
555 };
556 struct iovec iov[2] = {
557 { .iov_base = &nlh, .iov_len = sizeof nlh },
558 };
559 struct msghdr smsg = {
560 .msg_iov = iov,
561 .msg_iovlen = 2,
562 };
563 /* default destination for sending */
564 union sockaddr_union default_destination = {
565 .nl.nl_family = AF_NETLINK,
566 .nl.nl_groups = MONITOR_GROUP_UDEV,
567 };
568 uint64_t tag_bloom_bits;
569 const char *buf, *val;
570 ssize_t count;
571 size_t blen;
572 int r;
573
574 assert(m);
575 assert(device);
576
577 r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen);
578 if (r < 0)
579 return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device properties: %m");
580 if (blen < 32)
581 log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
582 "sd-device-monitor: Length of device property nulstr is too small to contain valid device information");
583
584 /* fill in versioned header */
585 r = sd_device_get_subsystem(device, &val);
586 if (r < 0)
587 return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device subsystem: %m");
588 nlh.filter_subsystem_hash = htobe32(string_hash32(val));
589
590 if (sd_device_get_devtype(device, &val) >= 0)
591 nlh.filter_devtype_hash = htobe32(string_hash32(val));
592
593 /* add tag bloom filter */
594 tag_bloom_bits = 0;
595 FOREACH_DEVICE_TAG(device, val)
596 tag_bloom_bits |= string_bloom64(val);
597
598 if (tag_bloom_bits > 0) {
599 nlh.filter_tag_bloom_hi = htobe32(tag_bloom_bits >> 32);
600 nlh.filter_tag_bloom_lo = htobe32(tag_bloom_bits & 0xffffffff);
601 }
602
603 /* add properties list */
604 nlh.properties_off = iov[0].iov_len;
605 nlh.properties_len = blen;
606 iov[1] = IOVEC_MAKE((char*) buf, blen);
607
608 /*
609 * Use custom address for target, or the default one.
610 *
611 * If we send to a multicast group, we will get
612 * ECONNREFUSED, which is expected.
613 */
614 smsg.msg_name = destination ? &destination->snl : &default_destination;
615 smsg.msg_namelen = sizeof(struct sockaddr_nl);
616 count = sendmsg(m->sock, &smsg, 0);
617 if (count < 0) {
618 if (!destination && errno == ECONNREFUSED) {
619 log_device_debug(device, "sd-device-monitor: Passed to netlink monitor");
620 return 0;
621 } else
622 return log_device_debug_errno(device, errno, "sd-device-monitor: Failed to send device to netlink monitor: %m");
623 }
624
625 log_device_debug(device, "sd-device-monitor: Passed %zi byte to netlink monitor", count);
626 return count;
627 }
628
bpf_stmt(struct sock_filter * ins,unsigned * i,unsigned short code,unsigned data)629 static void bpf_stmt(struct sock_filter *ins, unsigned *i,
630 unsigned short code, unsigned data) {
631 ins[(*i)++] = (struct sock_filter) {
632 .code = code,
633 .k = data,
634 };
635 }
636
bpf_jmp(struct sock_filter * ins,unsigned * i,unsigned short code,unsigned data,unsigned short jt,unsigned short jf)637 static void bpf_jmp(struct sock_filter *ins, unsigned *i,
638 unsigned short code, unsigned data,
639 unsigned short jt, unsigned short jf) {
640 ins[(*i)++] = (struct sock_filter) {
641 .code = code,
642 .jt = jt,
643 .jf = jf,
644 .k = data,
645 };
646 }
647
sd_device_monitor_filter_update(sd_device_monitor * m)648 _public_ int sd_device_monitor_filter_update(sd_device_monitor *m) {
649 struct sock_filter ins[512] = {};
650 struct sock_fprog filter;
651 const char *subsystem, *devtype, *tag;
652 unsigned i = 0;
653
654 assert_return(m, -EINVAL);
655
656 if (m->filter_uptodate)
657 return 0;
658
659 if (m->snl.nl.nl_groups == MONITOR_GROUP_KERNEL ||
660 (hashmap_isempty(m->subsystem_filter) &&
661 set_isempty(m->tag_filter))) {
662 m->filter_uptodate = true;
663 return 0;
664 }
665
666 /* load magic in A */
667 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(monitor_netlink_header, magic));
668 /* jump if magic matches */
669 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, UDEV_MONITOR_MAGIC, 1, 0);
670 /* wrong magic, pass packet */
671 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
672
673 if (!set_isempty(m->tag_filter)) {
674 int tag_matches = set_size(m->tag_filter);
675
676 /* add all tags matches */
677 SET_FOREACH(tag, m->tag_filter) {
678 uint64_t tag_bloom_bits = string_bloom64(tag);
679 uint32_t tag_bloom_hi = tag_bloom_bits >> 32;
680 uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff;
681
682 /* load device bloom bits in A */
683 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(monitor_netlink_header, filter_tag_bloom_hi));
684 /* clear bits (tag bits & bloom bits) */
685 bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_hi);
686 /* jump to next tag if it does not match */
687 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_hi, 0, 3);
688
689 /* load device bloom bits in A */
690 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(monitor_netlink_header, filter_tag_bloom_lo));
691 /* clear bits (tag bits & bloom bits) */
692 bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_lo);
693 /* jump behind end of tag match block if tag matches */
694 tag_matches--;
695 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_lo, 1 + (tag_matches * 6), 0);
696 }
697
698 /* nothing matched, drop packet */
699 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
700 }
701
702 /* add all subsystem matches */
703 if (!hashmap_isempty(m->subsystem_filter)) {
704 HASHMAP_FOREACH_KEY(devtype, subsystem, m->subsystem_filter) {
705 uint32_t hash = string_hash32(subsystem);
706
707 /* load device subsystem value in A */
708 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(monitor_netlink_header, filter_subsystem_hash));
709 if (!devtype) {
710 /* jump if subsystem does not match */
711 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
712 } else {
713 /* jump if subsystem does not match */
714 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3);
715 /* load device devtype value in A */
716 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(monitor_netlink_header, filter_devtype_hash));
717 /* jump if value does not match */
718 hash = string_hash32(devtype);
719 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
720 }
721
722 /* matched, pass packet */
723 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
724
725 if (i+1 >= ELEMENTSOF(ins))
726 return -E2BIG;
727 }
728
729 /* nothing matched, drop packet */
730 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
731 }
732
733 /* matched, pass packet */
734 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
735
736 /* install filter */
737 filter = (struct sock_fprog) {
738 .len = i,
739 .filter = ins,
740 };
741 if (setsockopt(m->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0)
742 return -errno;
743
744 m->filter_uptodate = true;
745 return 0;
746 }
747
sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor * m,const char * subsystem,const char * devtype)748 _public_ int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype) {
749 int r;
750
751 assert_return(m, -EINVAL);
752 assert_return(subsystem, -EINVAL);
753
754 /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
755 * multiple times with the same subsystem but different devtypes. */
756 r = hashmap_put_strdup_full(&m->subsystem_filter, &trivial_hash_ops_free_free, subsystem, devtype);
757 if (r <= 0)
758 return r;
759
760 m->filter_uptodate = false;
761 return r;
762 }
763
sd_device_monitor_filter_add_match_tag(sd_device_monitor * m,const char * tag)764 _public_ int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag) {
765 int r;
766
767 assert_return(m, -EINVAL);
768 assert_return(tag, -EINVAL);
769
770 r = set_put_strdup(&m->tag_filter, tag);
771 if (r <= 0)
772 return r;
773
774 m->filter_uptodate = false;
775 return r;
776 }
777
sd_device_monitor_filter_add_match_sysattr(sd_device_monitor * m,const char * sysattr,const char * value,int match)778 _public_ int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, const char *sysattr, const char *value, int match) {
779 Hashmap **hashmap;
780
781 assert_return(m, -EINVAL);
782 assert_return(sysattr, -EINVAL);
783
784 if (match)
785 hashmap = &m->match_sysattr_filter;
786 else
787 hashmap = &m->nomatch_sysattr_filter;
788
789 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
790 return hashmap_put_strdup_full(hashmap, &trivial_hash_ops_free_free, sysattr, value);
791 }
792
sd_device_monitor_filter_add_match_parent(sd_device_monitor * m,sd_device * device,int match)793 _public_ int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match) {
794 const char *syspath;
795 Set **set;
796 int r;
797
798 assert_return(m, -EINVAL);
799 assert_return(device, -EINVAL);
800
801 r = sd_device_get_syspath(device, &syspath);
802 if (r < 0)
803 return r;
804
805 if (match)
806 set = &m->match_parent_filter;
807 else
808 set = &m->nomatch_parent_filter;
809
810 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
811 return set_put_strdup(set, syspath);
812 }
813
sd_device_monitor_filter_remove(sd_device_monitor * m)814 _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) {
815 static const struct sock_fprog filter = { 0, NULL };
816
817 assert_return(m, -EINVAL);
818
819 m->subsystem_filter = hashmap_free(m->subsystem_filter);
820 m->tag_filter = set_free(m->tag_filter);
821 m->match_sysattr_filter = hashmap_free(m->match_sysattr_filter);
822 m->nomatch_sysattr_filter = hashmap_free(m->nomatch_sysattr_filter);
823 m->match_parent_filter = set_free(m->match_parent_filter);
824 m->nomatch_parent_filter = set_free(m->nomatch_parent_filter);
825
826 if (setsockopt(m->sock, SOL_SOCKET, SO_DETACH_FILTER, &filter, sizeof(filter)) < 0)
827 return -errno;
828
829 m->filter_uptodate = true;
830 return 0;
831 }
832