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