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