Line data Source code
1 : /***
2 : This file is part of systemd.
3 :
4 : Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 :
6 : systemd is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU Lesser General Public License as published by
8 : the Free Software Foundation; either version 2.1 of the License, or
9 : (at your option) any later version.
10 :
11 : systemd is distributed in the hope that it will be useful, but
12 : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should have received a copy of the GNU Lesser General Public License
17 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 : ***/
19 :
20 : #include <stdio.h>
21 : #include <stdlib.h>
22 : #include <stddef.h>
23 : #include <unistd.h>
24 : #include <errno.h>
25 : #include <string.h>
26 : #include <poll.h>
27 : #include <sys/socket.h>
28 : #include <linux/netlink.h>
29 : #include <linux/filter.h>
30 :
31 : #include "libudev.h"
32 : #include "libudev-private.h"
33 : #include "socket-util.h"
34 : #include "missing.h"
35 : #include "formats-util.h"
36 :
37 : /**
38 : * SECTION:libudev-monitor
39 : * @short_description: device event source
40 : *
41 : * Connects to a device event source.
42 : */
43 :
44 : /**
45 : * udev_monitor:
46 : *
47 : * Opaque object handling an event source.
48 : */
49 : struct udev_monitor {
50 : struct udev *udev;
51 : int refcount;
52 : int sock;
53 : union sockaddr_union snl;
54 : union sockaddr_union snl_trusted_sender;
55 : union sockaddr_union snl_destination;
56 : socklen_t addrlen;
57 : struct udev_list filter_subsystem_list;
58 : struct udev_list filter_tag_list;
59 : bool bound;
60 : };
61 :
62 : enum udev_monitor_netlink_group {
63 : UDEV_MONITOR_NONE,
64 : UDEV_MONITOR_KERNEL,
65 : UDEV_MONITOR_UDEV,
66 : };
67 :
68 : #define UDEV_MONITOR_MAGIC 0xfeedcafe
69 : struct udev_monitor_netlink_header {
70 : /* "libudev" prefix to distinguish libudev and kernel messages */
71 : char prefix[8];
72 : /*
73 : * magic to protect against daemon <-> library message format mismatch
74 : * used in the kernel from socket filter rules; needs to be stored in network order
75 : */
76 : unsigned int magic;
77 : /* total length of header structure known to the sender */
78 : unsigned int header_size;
79 : /* properties string buffer */
80 : unsigned int properties_off;
81 : unsigned int properties_len;
82 : /*
83 : * hashes of primary device properties strings, to let libudev subscribers
84 : * use in-kernel socket filters; values need to be stored in network order
85 : */
86 : unsigned int filter_subsystem_hash;
87 : unsigned int filter_devtype_hash;
88 : unsigned int filter_tag_bloom_hi;
89 : unsigned int filter_tag_bloom_lo;
90 : };
91 :
92 11 : static struct udev_monitor *udev_monitor_new(struct udev *udev)
93 : {
94 : struct udev_monitor *udev_monitor;
95 :
96 11 : udev_monitor = new0(struct udev_monitor, 1);
97 11 : if (udev_monitor == NULL)
98 0 : return NULL;
99 11 : udev_monitor->refcount = 1;
100 11 : udev_monitor->udev = udev;
101 11 : udev_list_init(udev, &udev_monitor->filter_subsystem_list, false);
102 11 : udev_list_init(udev, &udev_monitor->filter_tag_list, true);
103 11 : return udev_monitor;
104 : }
105 :
106 : /* we consider udev running when /dev is on devtmpfs */
107 0 : static bool udev_has_devtmpfs(struct udev *udev) {
108 :
109 0 : union file_handle_union h = FILE_HANDLE_INIT;
110 0 : _cleanup_fclose_ FILE *f = NULL;
111 : char line[LINE_MAX], *e;
112 : int mount_id;
113 : int r;
114 :
115 0 : r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0);
116 0 : if (r < 0) {
117 0 : if (errno != EOPNOTSUPP)
118 0 : log_debug_errno(errno, "name_to_handle_at on /dev: %m");
119 0 : return false;
120 : }
121 :
122 0 : f = fopen("/proc/self/mountinfo", "re");
123 0 : if (!f)
124 0 : return false;
125 :
126 0 : FOREACH_LINE(line, f, return false) {
127 : int mid;
128 :
129 0 : if (sscanf(line, "%i", &mid) != 1)
130 0 : continue;
131 :
132 0 : if (mid != mount_id)
133 0 : continue;
134 :
135 0 : e = strstr(line, " - ");
136 0 : if (!e)
137 0 : continue;
138 :
139 : /* accept any name that starts with the currently expected type */
140 0 : if (startswith(e + 3, "devtmpfs"))
141 0 : return true;
142 0 : }
143 :
144 0 : return false;
145 : }
146 :
147 11 : static void monitor_set_nl_address(struct udev_monitor *udev_monitor) {
148 : union sockaddr_union snl;
149 : socklen_t addrlen;
150 : int r;
151 :
152 11 : assert(udev_monitor);
153 :
154 : /* get the address the kernel has assigned us
155 : * it is usually, but not necessarily the pid
156 : */
157 11 : addrlen = sizeof(struct sockaddr_nl);
158 11 : r = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
159 11 : if (r >= 0)
160 11 : udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
161 11 : }
162 :
163 11 : struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
164 : {
165 : struct udev_monitor *udev_monitor;
166 : unsigned int group;
167 :
168 11 : if (udev == NULL)
169 0 : return NULL;
170 :
171 11 : if (name == NULL)
172 0 : group = UDEV_MONITOR_NONE;
173 11 : else if (streq(name, "udev")) {
174 : /*
175 : * We do not support subscribing to uevents if no instance of
176 : * udev is running. Uevents would otherwise broadcast the
177 : * processing data of the host into containers, which is not
178 : * desired.
179 : *
180 : * Containers will currently not get any udev uevents, until
181 : * a supporting infrastructure is available.
182 : *
183 : * We do not set a netlink multicast group here, so the socket
184 : * will not receive any messages.
185 : */
186 11 : if (access("/run/udev/control", F_OK) < 0 && !udev_has_devtmpfs(udev)) {
187 0 : log_debug("the udev service seems not to be active, disable the monitor");
188 0 : group = UDEV_MONITOR_NONE;
189 : } else
190 11 : group = UDEV_MONITOR_UDEV;
191 0 : } else if (streq(name, "kernel"))
192 0 : group = UDEV_MONITOR_KERNEL;
193 : else
194 0 : return NULL;
195 :
196 11 : udev_monitor = udev_monitor_new(udev);
197 11 : if (udev_monitor == NULL)
198 0 : return NULL;
199 :
200 11 : if (fd < 0) {
201 11 : udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
202 11 : if (udev_monitor->sock < 0) {
203 0 : log_debug_errno(errno, "error getting socket: %m");
204 0 : free(udev_monitor);
205 0 : return NULL;
206 : }
207 : } else {
208 0 : udev_monitor->bound = true;
209 0 : udev_monitor->sock = fd;
210 0 : monitor_set_nl_address(udev_monitor);
211 : }
212 :
213 11 : udev_monitor->snl.nl.nl_family = AF_NETLINK;
214 11 : udev_monitor->snl.nl.nl_groups = group;
215 :
216 : /* default destination for sending */
217 11 : udev_monitor->snl_destination.nl.nl_family = AF_NETLINK;
218 11 : udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV;
219 :
220 11 : return udev_monitor;
221 : }
222 :
223 : /**
224 : * udev_monitor_new_from_netlink:
225 : * @udev: udev library context
226 : * @name: name of event source
227 : *
228 : * Create new udev monitor and connect to a specified event
229 : * source. Valid sources identifiers are "udev" and "kernel".
230 : *
231 : * Applications should usually not connect directly to the
232 : * "kernel" events, because the devices might not be useable
233 : * at that time, before udev has configured them, and created
234 : * device nodes. Accessing devices at the same time as udev,
235 : * might result in unpredictable behavior. The "udev" events
236 : * are sent out after udev has finished its event processing,
237 : * all rules have been processed, and needed device nodes are
238 : * created.
239 : *
240 : * The initial refcount is 1, and needs to be decremented to
241 : * release the resources of the udev monitor.
242 : *
243 : * Returns: a new udev monitor, or #NULL, in case of an error
244 : **/
245 11 : _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name)
246 : {
247 11 : return udev_monitor_new_from_netlink_fd(udev, name, -1);
248 : }
249 :
250 86 : static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i,
251 : unsigned short code, unsigned int data)
252 : {
253 86 : struct sock_filter *ins = &inss[*i];
254 :
255 86 : ins->code = code;
256 86 : ins->k = data;
257 86 : (*i)++;
258 86 : }
259 :
260 32 : static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i,
261 : unsigned short code, unsigned int data,
262 : unsigned short jt, unsigned short jf)
263 : {
264 32 : struct sock_filter *ins = &inss[*i];
265 :
266 32 : ins->code = code;
267 32 : ins->jt = jt;
268 32 : ins->jf = jf;
269 32 : ins->k = data;
270 32 : (*i)++;
271 32 : }
272 :
273 : /**
274 : * udev_monitor_filter_update:
275 : * @udev_monitor: monitor
276 : *
277 : * Update the installed socket filter. This is only needed,
278 : * if the filter was removed or changed.
279 : *
280 : * Returns: 0 on success, otherwise a negative error value.
281 : */
282 11 : _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor)
283 : {
284 : struct sock_filter ins[512];
285 : struct sock_fprog filter;
286 : unsigned int i;
287 : struct udev_list_entry *list_entry;
288 : int err;
289 :
290 21 : if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL &&
291 10 : udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
292 0 : return 0;
293 :
294 11 : memzero(ins, sizeof(ins));
295 11 : i = 0;
296 :
297 : /* load magic in A */
298 11 : bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic));
299 : /* jump if magic matches */
300 11 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, UDEV_MONITOR_MAGIC, 1, 0);
301 : /* wrong magic, pass packet */
302 11 : bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
303 :
304 11 : if (udev_list_get_entry(&udev_monitor->filter_tag_list) != NULL) {
305 : int tag_matches;
306 :
307 : /* count tag matches, to calculate end of tag match block */
308 10 : tag_matches = 0;
309 20 : udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list))
310 10 : tag_matches++;
311 :
312 : /* add all tags matches */
313 20 : udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
314 10 : uint64_t tag_bloom_bits = util_string_bloom64(udev_list_entry_get_name(list_entry));
315 10 : uint32_t tag_bloom_hi = tag_bloom_bits >> 32;
316 10 : uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff;
317 :
318 : /* load device bloom bits in A */
319 10 : bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_hi));
320 : /* clear bits (tag bits & bloom bits) */
321 10 : bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_hi);
322 : /* jump to next tag if it does not match */
323 10 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_hi, 0, 3);
324 :
325 : /* load device bloom bits in A */
326 10 : bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_lo));
327 : /* clear bits (tag bits & bloom bits) */
328 10 : bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_lo);
329 : /* jump behind end of tag match block if tag matches */
330 10 : tag_matches--;
331 10 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_lo, 1 + (tag_matches * 6), 0);
332 : }
333 :
334 : /* nothing matched, drop packet */
335 10 : bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
336 : }
337 :
338 : /* add all subsystem matches */
339 11 : if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) != NULL) {
340 2 : udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
341 1 : unsigned int hash = util_string_hash32(udev_list_entry_get_name(list_entry));
342 :
343 : /* load device subsystem value in A */
344 1 : bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_subsystem_hash));
345 1 : if (udev_list_entry_get_value(list_entry) == NULL) {
346 : /* jump if subsystem does not match */
347 1 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
348 : } else {
349 : /* jump if subsystem does not match */
350 0 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3);
351 :
352 : /* load device devtype value in A */
353 0 : bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_devtype_hash));
354 : /* jump if value does not match */
355 0 : hash = util_string_hash32(udev_list_entry_get_value(list_entry));
356 0 : bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
357 : }
358 :
359 : /* matched, pass packet */
360 1 : bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
361 :
362 1 : if (i+1 >= ELEMENTSOF(ins))
363 0 : return -E2BIG;
364 : }
365 :
366 : /* nothing matched, drop packet */
367 1 : bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
368 : }
369 :
370 : /* matched, pass packet */
371 11 : bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
372 :
373 : /* install filter */
374 11 : memzero(&filter, sizeof(filter));
375 11 : filter.len = i;
376 11 : filter.filter = ins;
377 11 : err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
378 11 : return err < 0 ? -errno : 0;
379 : }
380 :
381 0 : int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender)
382 : {
383 0 : udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
384 0 : return 0;
385 : }
386 :
387 : /**
388 : * udev_monitor_enable_receiving:
389 : * @udev_monitor: the monitor which should receive events
390 : *
391 : * Binds the @udev_monitor socket to the event source.
392 : *
393 : * Returns: 0 on success, otherwise a negative error value.
394 : */
395 11 : _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
396 : {
397 11 : int err = 0;
398 11 : const int on = 1;
399 :
400 11 : udev_monitor_filter_update(udev_monitor);
401 :
402 11 : if (!udev_monitor->bound) {
403 11 : err = bind(udev_monitor->sock,
404 11 : &udev_monitor->snl.sa, sizeof(struct sockaddr_nl));
405 11 : if (err == 0)
406 11 : udev_monitor->bound = true;
407 : }
408 :
409 11 : if (err >= 0)
410 11 : monitor_set_nl_address(udev_monitor);
411 : else {
412 0 : log_debug_errno(errno, "bind failed: %m");
413 0 : return -errno;
414 : }
415 :
416 : /* enable receiving of sender credentials */
417 11 : err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
418 11 : if (err < 0)
419 0 : log_debug_errno(errno, "setting SO_PASSCRED failed: %m");
420 :
421 11 : return 0;
422 : }
423 :
424 : /**
425 : * udev_monitor_set_receive_buffer_size:
426 : * @udev_monitor: the monitor which should receive events
427 : * @size: the size in bytes
428 : *
429 : * Set the size of the kernel socket buffer. This call needs the
430 : * appropriate privileges to succeed.
431 : *
432 : * Returns: 0 on success, otherwise -1 on error.
433 : */
434 10 : _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size)
435 : {
436 10 : if (udev_monitor == NULL)
437 0 : return -EINVAL;
438 10 : return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
439 : }
440 :
441 0 : int udev_monitor_disconnect(struct udev_monitor *udev_monitor)
442 : {
443 : int err;
444 :
445 0 : err = close(udev_monitor->sock);
446 0 : udev_monitor->sock = -1;
447 0 : return err < 0 ? -errno : 0;
448 : }
449 :
450 : /**
451 : * udev_monitor_ref:
452 : * @udev_monitor: udev monitor
453 : *
454 : * Take a reference of a udev monitor.
455 : *
456 : * Returns: the passed udev monitor
457 : **/
458 0 : _public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor)
459 : {
460 0 : if (udev_monitor == NULL)
461 0 : return NULL;
462 0 : udev_monitor->refcount++;
463 0 : return udev_monitor;
464 : }
465 :
466 : /**
467 : * udev_monitor_unref:
468 : * @udev_monitor: udev monitor
469 : *
470 : * Drop a reference of a udev monitor. If the refcount reaches zero,
471 : * the bound socket will be closed, and the resources of the monitor
472 : * will be released.
473 : *
474 : * Returns: #NULL
475 : **/
476 11 : _public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor)
477 : {
478 11 : if (udev_monitor == NULL)
479 0 : return NULL;
480 11 : udev_monitor->refcount--;
481 11 : if (udev_monitor->refcount > 0)
482 0 : return NULL;
483 11 : if (udev_monitor->sock >= 0)
484 11 : close(udev_monitor->sock);
485 11 : udev_list_cleanup(&udev_monitor->filter_subsystem_list);
486 11 : udev_list_cleanup(&udev_monitor->filter_tag_list);
487 11 : free(udev_monitor);
488 11 : return NULL;
489 : }
490 :
491 : /**
492 : * udev_monitor_get_udev:
493 : * @udev_monitor: udev monitor
494 : *
495 : * Retrieve the udev library context the monitor was created with.
496 : *
497 : * Returns: the udev library context
498 : **/
499 0 : _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor)
500 : {
501 0 : if (udev_monitor == NULL)
502 0 : return NULL;
503 0 : return udev_monitor->udev;
504 : }
505 :
506 : /**
507 : * udev_monitor_get_fd:
508 : * @udev_monitor: udev monitor
509 : *
510 : * Retrieve the socket file descriptor associated with the monitor.
511 : *
512 : * Returns: the socket file descriptor
513 : **/
514 11 : _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor)
515 : {
516 11 : if (udev_monitor == NULL)
517 0 : return -EINVAL;
518 11 : return udev_monitor->sock;
519 : }
520 :
521 0 : static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device *udev_device)
522 : {
523 : struct udev_list_entry *list_entry;
524 :
525 0 : if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL)
526 0 : goto tag;
527 0 : udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
528 0 : const char *subsys = udev_list_entry_get_name(list_entry);
529 0 : const char *dsubsys = udev_device_get_subsystem(udev_device);
530 : const char *devtype;
531 : const char *ddevtype;
532 :
533 0 : if (!streq(dsubsys, subsys))
534 0 : continue;
535 :
536 0 : devtype = udev_list_entry_get_value(list_entry);
537 0 : if (devtype == NULL)
538 0 : goto tag;
539 0 : ddevtype = udev_device_get_devtype(udev_device);
540 0 : if (ddevtype == NULL)
541 0 : continue;
542 0 : if (streq(ddevtype, devtype))
543 0 : goto tag;
544 : }
545 0 : return 0;
546 :
547 : tag:
548 0 : if (udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
549 0 : return 1;
550 0 : udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
551 0 : const char *tag = udev_list_entry_get_name(list_entry);
552 :
553 0 : if (udev_device_has_tag(udev_device, tag))
554 0 : return 1;
555 : }
556 0 : return 0;
557 : }
558 :
559 : /**
560 : * udev_monitor_receive_device:
561 : * @udev_monitor: udev monitor
562 : *
563 : * Receive data from the udev monitor socket, allocate a new udev
564 : * device, fill in the received data, and return the device.
565 : *
566 : * Only socket connections with uid=0 are accepted.
567 : *
568 : * The monitor socket is by default set to NONBLOCK. A variant of poll() on
569 : * the file descriptor returned by udev_monitor_get_fd() should to be used to
570 : * wake up when new devices arrive, or alternatively the file descriptor
571 : * switched into blocking mode.
572 : *
573 : * The initial refcount is 1, and needs to be decremented to
574 : * release the resources of the udev device.
575 : *
576 : * Returns: a new udev device, or #NULL, in case of an error
577 : **/
578 0 : _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor)
579 : {
580 : struct udev_device *udev_device;
581 : struct msghdr smsg;
582 : struct iovec iov;
583 : char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
584 : struct cmsghdr *cmsg;
585 : union sockaddr_union snl;
586 : struct ucred *cred;
587 : union {
588 : struct udev_monitor_netlink_header nlh;
589 : char raw[8192];
590 : } buf;
591 : ssize_t buflen;
592 : ssize_t bufpos;
593 0 : bool is_initialized = false;
594 :
595 : retry:
596 0 : if (udev_monitor == NULL)
597 0 : return NULL;
598 0 : iov.iov_base = &buf;
599 0 : iov.iov_len = sizeof(buf);
600 0 : memzero(&smsg, sizeof(struct msghdr));
601 0 : smsg.msg_iov = &iov;
602 0 : smsg.msg_iovlen = 1;
603 0 : smsg.msg_control = cred_msg;
604 0 : smsg.msg_controllen = sizeof(cred_msg);
605 0 : smsg.msg_name = &snl;
606 0 : smsg.msg_namelen = sizeof(snl);
607 :
608 0 : buflen = recvmsg(udev_monitor->sock, &smsg, 0);
609 0 : if (buflen < 0) {
610 0 : if (errno != EINTR)
611 0 : log_debug("unable to receive message");
612 0 : return NULL;
613 : }
614 :
615 0 : if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) {
616 0 : log_debug("invalid message length");
617 0 : return NULL;
618 : }
619 :
620 0 : if (snl.nl.nl_groups == 0) {
621 : /* unicast message, check if we trust the sender */
622 0 : if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 ||
623 0 : snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) {
624 0 : log_debug("unicast netlink message ignored");
625 0 : return NULL;
626 : }
627 0 : } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) {
628 0 : if (snl.nl.nl_pid > 0) {
629 0 : log_debug("multicast kernel netlink message from PID %"PRIu32" ignored",
630 : snl.nl.nl_pid);
631 0 : return NULL;
632 : }
633 : }
634 :
635 0 : cmsg = CMSG_FIRSTHDR(&smsg);
636 0 : if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
637 0 : log_debug("no sender credentials received, message ignored");
638 0 : return NULL;
639 : }
640 :
641 0 : cred = (struct ucred *)CMSG_DATA(cmsg);
642 0 : if (cred->uid != 0) {
643 0 : log_debug("sender uid="UID_FMT", message ignored", cred->uid);
644 0 : return NULL;
645 : }
646 :
647 0 : if (memcmp(buf.raw, "libudev", 8) == 0) {
648 : /* udev message needs proper version magic */
649 0 : if (buf.nlh.magic != htonl(UDEV_MONITOR_MAGIC)) {
650 0 : log_debug("unrecognized message signature (%x != %x)",
651 : buf.nlh.magic, htonl(UDEV_MONITOR_MAGIC));
652 0 : return NULL;
653 : }
654 0 : if (buf.nlh.properties_off+32 > (size_t)buflen) {
655 0 : log_debug("message smaller than expected (%u > %zd)",
656 : buf.nlh.properties_off+32, buflen);
657 0 : return NULL;
658 : }
659 :
660 0 : bufpos = buf.nlh.properties_off;
661 :
662 : /* devices received from udev are always initialized */
663 0 : is_initialized = true;
664 : } else {
665 : /* kernel message with header */
666 0 : bufpos = strlen(buf.raw) + 1;
667 0 : if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) {
668 0 : log_debug("invalid message length");
669 0 : return NULL;
670 : }
671 :
672 : /* check message header */
673 0 : if (strstr(buf.raw, "@/") == NULL) {
674 0 : log_debug("unrecognized message header");
675 0 : return NULL;
676 : }
677 : }
678 :
679 0 : udev_device = udev_device_new_from_nulstr(udev_monitor->udev, &buf.raw[bufpos], buflen - bufpos);
680 0 : if (!udev_device) {
681 0 : log_debug("could not create device: %m");
682 0 : return NULL;
683 : }
684 :
685 0 : if (is_initialized)
686 0 : udev_device_set_is_initialized(udev_device);
687 :
688 : /* skip device, if it does not pass the current filter */
689 0 : if (!passes_filter(udev_monitor, udev_device)) {
690 : struct pollfd pfd[1];
691 : int rc;
692 :
693 0 : udev_device_unref(udev_device);
694 :
695 : /* if something is queued, get next device */
696 0 : pfd[0].fd = udev_monitor->sock;
697 0 : pfd[0].events = POLLIN;
698 0 : rc = poll(pfd, 1, 0);
699 0 : if (rc > 0)
700 0 : goto retry;
701 0 : return NULL;
702 : }
703 :
704 0 : return udev_device;
705 : }
706 :
707 0 : int udev_monitor_send_device(struct udev_monitor *udev_monitor,
708 : struct udev_monitor *destination, struct udev_device *udev_device)
709 : {
710 : const char *buf, *val;
711 : ssize_t blen, count;
712 0 : struct udev_monitor_netlink_header nlh = {
713 : .prefix = "libudev",
714 0 : .magic = htonl(UDEV_MONITOR_MAGIC),
715 : .header_size = sizeof nlh,
716 : };
717 0 : struct iovec iov[2] = {
718 : { .iov_base = &nlh, .iov_len = sizeof nlh },
719 : };
720 0 : struct msghdr smsg = {
721 : .msg_iov = iov,
722 : .msg_iovlen = 2,
723 : };
724 : struct udev_list_entry *list_entry;
725 : uint64_t tag_bloom_bits;
726 :
727 0 : blen = udev_device_get_properties_monitor_buf(udev_device, &buf);
728 0 : if (blen < 32) {
729 0 : log_debug("device buffer is too small to contain a valid device");
730 0 : return -EINVAL;
731 : }
732 :
733 : /* fill in versioned header */
734 0 : val = udev_device_get_subsystem(udev_device);
735 0 : nlh.filter_subsystem_hash = htonl(util_string_hash32(val));
736 :
737 0 : val = udev_device_get_devtype(udev_device);
738 0 : if (val != NULL)
739 0 : nlh.filter_devtype_hash = htonl(util_string_hash32(val));
740 :
741 : /* add tag bloom filter */
742 0 : tag_bloom_bits = 0;
743 0 : udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
744 0 : tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry));
745 0 : if (tag_bloom_bits > 0) {
746 0 : nlh.filter_tag_bloom_hi = htonl(tag_bloom_bits >> 32);
747 0 : nlh.filter_tag_bloom_lo = htonl(tag_bloom_bits & 0xffffffff);
748 : }
749 :
750 : /* add properties list */
751 0 : nlh.properties_off = iov[0].iov_len;
752 0 : nlh.properties_len = blen;
753 0 : iov[1].iov_base = (char *)buf;
754 0 : iov[1].iov_len = blen;
755 :
756 : /*
757 : * Use custom address for target, or the default one.
758 : *
759 : * If we send to a multicast group, we will get
760 : * ECONNREFUSED, which is expected.
761 : */
762 0 : if (destination)
763 0 : smsg.msg_name = &destination->snl;
764 : else
765 0 : smsg.msg_name = &udev_monitor->snl_destination;
766 0 : smsg.msg_namelen = sizeof(struct sockaddr_nl);
767 0 : count = sendmsg(udev_monitor->sock, &smsg, 0);
768 0 : if (count < 0) {
769 0 : if (!destination && errno == ECONNREFUSED) {
770 0 : log_debug("passed device to netlink monitor %p", udev_monitor);
771 0 : return 0;
772 : } else
773 0 : return -errno;
774 : }
775 :
776 0 : log_debug("passed %zi byte device to netlink monitor %p", count, udev_monitor);
777 0 : return count;
778 : }
779 :
780 : /**
781 : * udev_monitor_filter_add_match_subsystem_devtype:
782 : * @udev_monitor: the monitor
783 : * @subsystem: the subsystem value to match the incoming devices against
784 : * @devtype: the devtype value to match the incoming devices against
785 : *
786 : * This filter is efficiently executed inside the kernel, and libudev subscribers
787 : * will usually not be woken up for devices which do not match.
788 : *
789 : * The filter must be installed before the monitor is switched to listening mode.
790 : *
791 : * Returns: 0 on success, otherwise a negative error value.
792 : */
793 1 : _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype)
794 : {
795 1 : if (udev_monitor == NULL)
796 0 : return -EINVAL;
797 1 : if (subsystem == NULL)
798 0 : return -EINVAL;
799 1 : if (udev_list_entry_add(&udev_monitor->filter_subsystem_list, subsystem, devtype) == NULL)
800 0 : return -ENOMEM;
801 1 : return 0;
802 : }
803 :
804 : /**
805 : * udev_monitor_filter_add_match_tag:
806 : * @udev_monitor: the monitor
807 : * @tag: the name of a tag
808 : *
809 : * This filter is efficiently executed inside the kernel, and libudev subscribers
810 : * will usually not be woken up for devices which do not match.
811 : *
812 : * The filter must be installed before the monitor is switched to listening mode.
813 : *
814 : * Returns: 0 on success, otherwise a negative error value.
815 : */
816 10 : _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag)
817 : {
818 10 : if (udev_monitor == NULL)
819 0 : return -EINVAL;
820 10 : if (tag == NULL)
821 0 : return -EINVAL;
822 10 : if (udev_list_entry_add(&udev_monitor->filter_tag_list, tag, NULL) == NULL)
823 0 : return -ENOMEM;
824 10 : return 0;
825 : }
826 :
827 : /**
828 : * udev_monitor_filter_remove:
829 : * @udev_monitor: monitor
830 : *
831 : * Remove all filters from monitor.
832 : *
833 : * Returns: 0 on success, otherwise a negative error value.
834 : */
835 0 : _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor)
836 : {
837 : static struct sock_fprog filter = { 0, NULL };
838 :
839 0 : udev_list_cleanup(&udev_monitor->filter_subsystem_list);
840 0 : return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
841 : }
|