]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udev-node.c
Merge pull request #23927 from AndreKalb/feature/ipv4-link-local-start-address
[thirdparty/systemd.git] / src / udev / udev-node.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9
10 #include "sd-id128.h"
11
12 #include "alloc-util.h"
13 #include "device-private.h"
14 #include "device-util.h"
15 #include "devnum-util.h"
16 #include "dirent-util.h"
17 #include "escape.h"
18 #include "fd-util.h"
19 #include "format-util.h"
20 #include "fs-util.h"
21 #include "hexdecoct.h"
22 #include "mkdir-label.h"
23 #include "parse-util.h"
24 #include "path-util.h"
25 #include "random-util.h"
26 #include "selinux-util.h"
27 #include "smack-util.h"
28 #include "stat-util.h"
29 #include "stdio-util.h"
30 #include "string-util.h"
31 #include "strxcpyx.h"
32 #include "time-util.h"
33 #include "udev-node.h"
34 #include "user-util.h"
35
36 #define CREATE_LINK_MAX_RETRIES 128
37 #define LINK_UPDATE_MAX_RETRIES 128
38 #define CREATE_STACK_LINK_MAX_RETRIES 128
39 #define UPDATE_TIMESTAMP_MAX_RETRIES 128
40 #define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC)
41 #define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC)
42 #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f)
43
44 static int create_symlink(const char *target, const char *slink) {
45 int r;
46
47 assert(target);
48 assert(slink);
49
50 for (unsigned i = 0; i < CREATE_LINK_MAX_RETRIES; i++) {
51 r = mkdir_parents_label(slink, 0755);
52 if (r == -ENOENT)
53 continue;
54 if (r < 0)
55 return r;
56
57 mac_selinux_create_file_prepare(slink, S_IFLNK);
58 r = RET_NERRNO(symlink(target, slink));
59 mac_selinux_create_file_clear();
60 if (r != -ENOENT)
61 return r;
62 }
63
64 return r;
65 }
66
67 static int node_symlink(sd_device *dev, const char *node, const char *slink) {
68 _cleanup_free_ char *slink_dirname = NULL, *target = NULL;
69 const char *id, *slink_tmp;
70 struct stat stats;
71 int r;
72
73 assert(dev);
74 assert(node);
75 assert(slink);
76
77 if (lstat(slink, &stats) >= 0) {
78 if (!S_ISLNK(stats.st_mode))
79 return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST),
80 "Conflicting inode '%s' found, link to '%s' will not be created.", slink, node);
81 } else if (errno != ENOENT)
82 return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink);
83
84 r = path_extract_directory(slink, &slink_dirname);
85 if (r < 0)
86 return log_device_debug_errno(dev, r, "Failed to get parent directory of '%s': %m", slink);
87
88 /* use relative link */
89 r = path_make_relative(slink_dirname, node, &target);
90 if (r < 0)
91 return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, node);
92
93 r = device_get_device_id(dev, &id);
94 if (r < 0)
95 return log_device_debug_errno(dev, r, "Failed to get device id: %m");
96
97 slink_tmp = strjoina(slink, ".tmp-", id);
98 (void) unlink(slink_tmp);
99
100 r = create_symlink(target, slink_tmp);
101 if (r < 0)
102 return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target);
103
104 if (rename(slink_tmp, slink) < 0) {
105 r = log_device_debug_errno(dev, errno, "Failed to rename '%s' to '%s': %m", slink_tmp, slink);
106 (void) unlink(slink_tmp);
107 return r;
108 }
109
110 return 0;
111 }
112
113 static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) {
114 _cleanup_closedir_ DIR *dir = NULL;
115 _cleanup_free_ char *target = NULL;
116 int r, priority = 0;
117 const char *id;
118
119 assert(dev);
120 assert(stackdir);
121 assert(ret);
122
123 /* Find device node of device with highest priority. This returns 1 if a device found, 0 if no
124 * device found, or a negative errno. */
125
126 if (add) {
127 const char *devnode;
128
129 r = device_get_devlink_priority(dev, &priority);
130 if (r < 0)
131 return r;
132
133 r = sd_device_get_devname(dev, &devnode);
134 if (r < 0)
135 return r;
136
137 target = strdup(devnode);
138 if (!target)
139 return -ENOMEM;
140 }
141
142 dir = opendir(stackdir);
143 if (!dir) {
144 if (add) /* The stack directory must exist. */
145 return -errno;
146 if (errno != ENOENT)
147 return -errno;
148
149 *ret = NULL;
150 return 0;
151 }
152
153 r = device_get_device_id(dev, &id);
154 if (r < 0)
155 return r;
156
157 FOREACH_DIRENT_ALL(de, dir, break) {
158 _cleanup_free_ char *path = NULL, *buf = NULL;
159 int tmp_prio;
160
161 if (de->d_name[0] == '.')
162 continue;
163
164 /* skip ourself */
165 if (streq(de->d_name, id))
166 continue;
167
168 path = path_join(stackdir, de->d_name);
169 if (!path)
170 return -ENOMEM;
171
172 if (readlink_malloc(path, &buf) >= 0) {
173 char *devnode;
174
175 /* New format. The devnode and priority can be obtained from symlink. */
176
177 devnode = strchr(buf, ':');
178 if (!devnode || devnode == buf)
179 continue;
180
181 *(devnode++) = '\0';
182 if (!path_startswith(devnode, "/dev"))
183 continue;
184
185 if (safe_atoi(buf, &tmp_prio) < 0)
186 continue;
187
188 if (target && tmp_prio <= priority)
189 continue;
190
191 r = free_and_strdup(&target, devnode);
192 if (r < 0)
193 return r;
194 } else {
195 _cleanup_(sd_device_unrefp) sd_device *tmp_dev = NULL;
196 const char *devnode;
197
198 /* Old format. The devnode and priority must be obtained from uevent and
199 * udev database files. */
200
201 if (sd_device_new_from_device_id(&tmp_dev, de->d_name) < 0)
202 continue;
203
204 if (device_get_devlink_priority(tmp_dev, &tmp_prio) < 0)
205 continue;
206
207 if (target && tmp_prio <= priority)
208 continue;
209
210 if (sd_device_get_devname(tmp_dev, &devnode) < 0)
211 continue;
212
213 r = free_and_strdup(&target, devnode);
214 if (r < 0)
215 return r;
216 }
217
218 priority = tmp_prio;
219 }
220
221 *ret = TAKE_PTR(target);
222 return !!*ret;
223 }
224
225 size_t udev_node_escape_path(const char *src, char *dest, size_t size) {
226 size_t i, j;
227 uint64_t h;
228
229 assert(src);
230 assert(dest);
231 assert(size >= 12);
232
233 for (i = 0, j = 0; src[i] != '\0'; i++) {
234 if (src[i] == '/') {
235 if (j+4 >= size - 12 + 1)
236 goto toolong;
237 memcpy(&dest[j], "\\x2f", 4);
238 j += 4;
239 } else if (src[i] == '\\') {
240 if (j+4 >= size - 12 + 1)
241 goto toolong;
242 memcpy(&dest[j], "\\x5c", 4);
243 j += 4;
244 } else {
245 if (j+1 >= size - 12 + 1)
246 goto toolong;
247 dest[j] = src[i];
248 j++;
249 }
250 }
251 dest[j] = '\0';
252 return j;
253
254 toolong:
255 /* If the input path is too long to encode as a filename, then let's suffix with a string
256 * generated from the hash of the path. */
257
258 h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes);
259
260 for (unsigned k = 0; k <= 10; k++)
261 dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & 63);
262
263 dest[size - 1] = '\0';
264 return size - 1;
265 }
266
267 static int update_timestamp(sd_device *dev, const char *path, struct stat *prev) {
268 assert(path);
269 assert(prev);
270
271 /* Even if a symlink in the stack directory is created/removed, the mtime of the directory may
272 * not be changed. Why? Let's consider the following situation. For simplicity, let's assume
273 * there exist two udev workers (A and B) and all of them calls link_update() for the same
274 * devlink simultaneously.
275 *
276 * 1. A creates/removes a symlink in the stack directory.
277 * 2. A calls the first stat() in the loop of link_update().
278 * 3. A calls link_find_prioritized().
279 * 4. B creates/removes another symlink in the stack directory, so the result of the step 3 is outdated.
280 * 5. B finishes link_update().
281 * 6. A creates/removes devlink according to the outdated result in the step 3.
282 * 7. A calls the second stat() in the loop of link_update().
283 *
284 * If these 7 steps are processed in this order within a short time period that kernel's timer
285 * does not increase, then even if the contents in the stack directory is changed, the results
286 * of two stat() called by A shows the same timestamp, and A cannot detect the change.
287 *
288 * By calling this function after creating/removing symlinks in the stack directory, the
289 * timestamp of the stack directory is always increased at least in the above step 5, so A can
290 * detect the update. */
291
292 if ((prev->st_mode & S_IFMT) == 0)
293 return 0; /* Does not exist, or previous stat() failed. */
294
295 for (unsigned i = 0; i < UPDATE_TIMESTAMP_MAX_RETRIES; i++) {
296 struct stat st;
297
298 if (stat(path, &st) < 0)
299 return -errno;
300
301 if (!stat_inode_unmodified(prev, &st))
302 return 0;
303
304 log_device_debug(dev,
305 "%s is modified, but its timestamp is not changed, "
306 "updating timestamp after 10ms.",
307 path);
308
309 (void) usleep(10 * USEC_PER_MSEC);
310 if (utimensat(AT_FDCWD, path, NULL, 0) < 0)
311 return -errno;
312 }
313
314 return -ELOOP;
315 }
316
317 static int update_stack_directory(sd_device *dev, const char *dirname, bool add) {
318 _cleanup_free_ char *filename = NULL, *data = NULL, *buf = NULL;
319 const char *devname, *id;
320 struct stat st = {};
321 int priority, r;
322
323 assert(dev);
324 assert(dirname);
325
326 r = device_get_device_id(dev, &id);
327 if (r < 0)
328 return log_device_debug_errno(dev, r, "Failed to get device id: %m");
329
330 filename = path_join(dirname, id);
331 if (!filename)
332 return log_oom_debug();
333
334 if (!add) {
335 int unlink_error = 0, stat_error = 0;
336
337 if (stat(dirname, &st) < 0) {
338 if (errno == ENOENT)
339 return 0; /* The stack directory is already removed. That's OK. */
340 stat_error = -errno;
341 }
342
343 if (unlink(filename) < 0)
344 unlink_error = -errno;
345
346 if (rmdir(dirname) >= 0 || errno == ENOENT)
347 return 0;
348
349 if (unlink_error < 0) {
350 if (unlink_error == -ENOENT)
351 return 0;
352
353 /* If we failed to remove the symlink, then there is almost nothing we can do. */
354 return log_device_debug_errno(dev, unlink_error, "Failed to remove %s: %m", filename);
355 }
356
357 if (stat_error < 0)
358 return log_device_debug_errno(dev, stat_error, "Failed to stat %s: %m", dirname);
359
360 /* The symlink was removed. Check if the timestamp of directory is changed. */
361 r = update_timestamp(dev, dirname, &st);
362 if (r < 0 && r != -ENOENT)
363 return log_device_debug_errno(dev, r, "Failed to update timestamp of %s: %m", dirname);
364
365 return 0;
366 }
367
368 r = sd_device_get_devname(dev, &devname);
369 if (r < 0)
370 return log_device_debug_errno(dev, r, "Failed to get device node: %m");
371
372 r = device_get_devlink_priority(dev, &priority);
373 if (r < 0)
374 return log_device_debug_errno(dev, r, "Failed to get priority of device node symlink: %m");
375
376 if (asprintf(&data, "%i:%s", priority, devname) < 0)
377 return log_oom_debug();
378
379 if (readlink_malloc(filename, &buf) >= 0 && streq(buf, data))
380 return 0;
381
382 if (unlink(filename) < 0 && errno != ENOENT)
383 log_device_debug_errno(dev, errno, "Failed to remove %s, ignoring: %m", filename);
384
385 for (unsigned j = 0; j < CREATE_STACK_LINK_MAX_RETRIES; j++) {
386 /* This may fail with -ENOENT when the parent directory is removed during
387 * creating the file by another udevd worker. */
388 r = mkdir_p(dirname, 0755);
389 if (r == -ENOENT)
390 continue;
391 if (r < 0)
392 return log_device_debug_errno(dev, r, "Failed to create directory %s: %m", dirname);
393
394 if (stat(dirname, &st) < 0) {
395 if (errno == ENOENT)
396 continue;
397 return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname);
398 }
399
400 if (symlink(data, filename) < 0) {
401 if (errno == ENOENT)
402 continue;
403 return log_device_debug_errno(dev, errno, "Failed to create symbolic link %s: %m", filename);
404 }
405
406 /* The symlink was created. Check if the timestamp of directory is changed. */
407 r = update_timestamp(dev, dirname, &st);
408 if (r < 0)
409 return log_device_debug_errno(dev, r, "Failed to update timestamp of %s: %m", dirname);
410
411 return 0;
412 }
413
414 return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ELOOP), "Failed to create symbolic link %s: %m", filename);
415 }
416
417 /* manage "stack of names" with possibly specified device priorities */
418 static int link_update(sd_device *dev, const char *slink_in, bool add) {
419 _cleanup_free_ char *slink = NULL, *dirname = NULL;
420 const char *slink_name;
421 char name_enc[NAME_MAX+1];
422 int r;
423
424 assert(dev);
425 assert(slink_in);
426
427 slink = strdup(slink_in);
428 if (!slink)
429 return log_oom_debug();
430
431 path_simplify(slink);
432
433 slink_name = path_startswith(slink, "/dev");
434 if (!slink_name ||
435 empty_or_root(slink_name) ||
436 !path_is_normalized(slink_name))
437 return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL),
438 "Invalid symbolic link of device node: %s", slink);
439
440 (void) udev_node_escape_path(slink_name, name_enc, sizeof(name_enc));
441 dirname = path_join("/run/udev/links", name_enc);
442 if (!dirname)
443 return log_oom_debug();
444
445 r = update_stack_directory(dev, dirname, add);
446 if (r < 0)
447 return r;
448
449 for (unsigned i = 0; i < LINK_UPDATE_MAX_RETRIES; i++) {
450 _cleanup_free_ char *target = NULL;
451 struct stat st1 = {}, st2 = {};
452
453 if (i > 0) {
454 usec_t delay = MIN_RANDOM_DELAY + random_u64_range(MAX_RANDOM_DELAY - MIN_RANDOM_DELAY);
455
456 log_device_debug(dev, "Directory %s was updated, retrying to update devlink %s after %s.",
457 dirname, slink, FORMAT_TIMESPAN(delay, USEC_PER_MSEC));
458 (void) usleep(delay);
459 }
460
461 if (stat(dirname, &st1) < 0 && errno != ENOENT)
462 return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname);
463
464 r = link_find_prioritized(dev, add, dirname, &target);
465 if (r < 0)
466 return log_device_debug_errno(dev, r, "Failed to determine device node with the highest priority for '%s': %m", slink);
467 if (r == 0) {
468 log_device_debug(dev, "No reference left for '%s', removing", slink);
469
470 if (unlink(slink) < 0 && errno != ENOENT)
471 log_device_debug_errno(dev, errno, "Failed to remove '%s', ignoring: %m", slink);
472
473 (void) rmdir_parents(slink, "/dev");
474 return 0;
475 }
476
477 r = node_symlink(dev, target, slink);
478 if (r < 0)
479 return r;
480
481 if (stat(dirname, &st2) < 0 && errno != ENOENT)
482 return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname);
483
484 if (((st1.st_mode & S_IFMT) == 0 && (st2.st_mode & S_IFMT) == 0) ||
485 stat_inode_unmodified(&st1, &st2))
486 return 0;
487 }
488
489 return -ELOOP;
490 }
491
492 static int device_get_devpath_by_devnum(sd_device *dev, char **ret) {
493 const char *subsystem;
494 dev_t devnum;
495 int r;
496
497 assert(dev);
498 assert(ret);
499
500 r = sd_device_get_subsystem(dev, &subsystem);
501 if (r < 0)
502 return r;
503
504 r = sd_device_get_devnum(dev, &devnum);
505 if (r < 0)
506 return r;
507
508 return device_path_make_major_minor(streq(subsystem, "block") ? S_IFBLK : S_IFCHR, devnum, ret);
509 }
510
511 int udev_node_update(sd_device *dev, sd_device *dev_old) {
512 _cleanup_free_ char *filename = NULL;
513 const char *devnode, *devlink;
514 int r;
515
516 assert(dev);
517 assert(dev_old);
518
519 r = sd_device_get_devname(dev, &devnode);
520 if (r < 0)
521 return log_device_debug_errno(dev, r, "Failed to get devnode: %m");
522
523 if (DEBUG_LOGGING) {
524 const char *id = NULL;
525
526 (void) device_get_device_id(dev, &id);
527 log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id));
528 }
529
530 /* update possible left-over symlinks */
531 FOREACH_DEVICE_DEVLINK(dev_old, devlink) {
532 /* check if old link name still belongs to this device */
533 if (device_has_devlink(dev, devlink))
534 continue;
535
536 log_device_debug(dev,
537 "Removing/updating old device symlink '%s', which is no longer belonging to this device.",
538 devlink);
539
540 r = link_update(dev, devlink, /* add = */ false);
541 if (r < 0)
542 log_device_warning_errno(dev, r,
543 "Failed to remove/update device symlink '%s', ignoring: %m",
544 devlink);
545 }
546
547 /* create/update symlinks, add symlinks to name index */
548 FOREACH_DEVICE_DEVLINK(dev, devlink) {
549 r = link_update(dev, devlink, /* add = */ true);
550 if (r < 0)
551 log_device_warning_errno(dev, r,
552 "Failed to create/update device symlink '%s', ignoring: %m",
553 devlink);
554 }
555
556 r = device_get_devpath_by_devnum(dev, &filename);
557 if (r < 0)
558 return log_device_debug_errno(dev, r, "Failed to get device path: %m");
559
560 /* always add /dev/{block,char}/$major:$minor */
561 r = node_symlink(dev, devnode, filename);
562 if (r < 0)
563 return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename);
564
565 return 0;
566 }
567
568 int udev_node_remove(sd_device *dev) {
569 _cleanup_free_ char *filename = NULL;
570 const char *devlink;
571 int r;
572
573 assert(dev);
574
575 /* remove/update symlinks, remove symlinks from name index */
576 FOREACH_DEVICE_DEVLINK(dev, devlink) {
577 r = link_update(dev, devlink, /* add = */ false);
578 if (r < 0)
579 log_device_warning_errno(dev, r,
580 "Failed to remove/update device symlink '%s', ignoring: %m",
581 devlink);
582 }
583
584 r = device_get_devpath_by_devnum(dev, &filename);
585 if (r < 0)
586 return log_device_debug_errno(dev, r, "Failed to get device path: %m");
587
588 /* remove /dev/{block,char}/$major:$minor */
589 if (unlink(filename) < 0 && errno != ENOENT)
590 return log_device_debug_errno(dev, errno, "Failed to remove '%s': %m", filename);
591
592 return 0;
593 }
594
595 static int udev_node_apply_permissions_impl(
596 sd_device *dev, /* can be NULL, only used for logging. */
597 int node_fd,
598 const char *devnode,
599 bool apply_mac,
600 mode_t mode,
601 uid_t uid,
602 gid_t gid,
603 OrderedHashmap *seclabel_list) {
604
605 bool apply_mode, apply_uid, apply_gid;
606 struct stat stats;
607 int r;
608
609 assert(node_fd >= 0);
610 assert(devnode);
611
612 if (fstat(node_fd, &stats) < 0)
613 return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode);
614
615 /* If group is set, but mode is not set, "upgrade" mode for the group. */
616 if (mode == MODE_INVALID && gid_is_valid(gid) && gid > 0)
617 mode = 0660;
618
619 apply_mode = mode != MODE_INVALID && (stats.st_mode & 0777) != (mode & 0777);
620 apply_uid = uid_is_valid(uid) && stats.st_uid != uid;
621 apply_gid = gid_is_valid(gid) && stats.st_gid != gid;
622
623 if (apply_mode || apply_uid || apply_gid || apply_mac) {
624 bool selinux = false, smack = false;
625 const char *name, *label;
626
627 if (apply_mode || apply_uid || apply_gid) {
628 log_device_debug(dev, "Setting permissions %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o",
629 devnode,
630 uid_is_valid(uid) ? uid : stats.st_uid,
631 gid_is_valid(gid) ? gid : stats.st_gid,
632 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
633
634 r = fchmod_and_chown(node_fd, mode, uid, gid);
635 if (r < 0)
636 log_device_full_errno(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r,
637 "Failed to set owner/mode of %s to uid=" UID_FMT
638 ", gid=" GID_FMT ", mode=%#o: %m",
639 devnode,
640 uid_is_valid(uid) ? uid : stats.st_uid,
641 gid_is_valid(gid) ? gid : stats.st_gid,
642 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
643 } else
644 log_device_debug(dev, "Preserve permissions of %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o",
645 devnode,
646 uid_is_valid(uid) ? uid : stats.st_uid,
647 gid_is_valid(gid) ? gid : stats.st_gid,
648 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
649
650 /* apply SECLABEL{$module}=$label */
651 ORDERED_HASHMAP_FOREACH_KEY(label, name, seclabel_list) {
652 int q;
653
654 if (streq(name, "selinux")) {
655 selinux = true;
656
657 q = mac_selinux_apply_fd(node_fd, devnode, label);
658 if (q < 0)
659 log_device_full_errno(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
660 "SECLABEL: failed to set SELinux label '%s': %m", label);
661 else
662 log_device_debug(dev, "SECLABEL: set SELinux label '%s'", label);
663
664 } else if (streq(name, "smack")) {
665 smack = true;
666
667 q = mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, label);
668 if (q < 0)
669 log_device_full_errno(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
670 "SECLABEL: failed to set SMACK label '%s': %m", label);
671 else
672 log_device_debug(dev, "SECLABEL: set SMACK label '%s'", label);
673
674 } else
675 log_device_error(dev, "SECLABEL: unknown subsystem, ignoring '%s'='%s'", name, label);
676 }
677
678 /* set the defaults */
679 if (!selinux)
680 (void) mac_selinux_fix_full(node_fd, NULL, devnode, LABEL_IGNORE_ENOENT);
681 if (!smack)
682 (void) mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, NULL);
683 }
684
685 /* always update timestamp when we re-use the node, like on media change events */
686 r = futimens_opath(node_fd, NULL);
687 if (r < 0)
688 log_device_debug_errno(dev, r, "Failed to adjust timestamp of node %s: %m", devnode);
689
690 return 0;
691 }
692
693 int udev_node_apply_permissions(
694 sd_device *dev,
695 bool apply_mac,
696 mode_t mode,
697 uid_t uid,
698 gid_t gid,
699 OrderedHashmap *seclabel_list) {
700
701 const char *devnode;
702 _cleanup_close_ int node_fd = -1;
703 int r;
704
705 assert(dev);
706
707 r = sd_device_get_devname(dev, &devnode);
708 if (r < 0)
709 return log_device_debug_errno(dev, r, "Failed to get devname: %m");
710
711 node_fd = sd_device_open(dev, O_PATH|O_CLOEXEC);
712 if (node_fd < 0) {
713 if (ERRNO_IS_DEVICE_ABSENT(node_fd)) {
714 log_device_debug_errno(dev, node_fd, "Device node %s is missing, skipping handling.", devnode);
715 return 0; /* This is necessarily racey, so ignore missing the device */
716 }
717
718 return log_device_debug_errno(dev, node_fd, "Cannot open node %s: %m", devnode);
719 }
720
721 return udev_node_apply_permissions_impl(dev, node_fd, devnode, apply_mac, mode, uid, gid, seclabel_list);
722 }
723
724 int static_node_apply_permissions(
725 const char *name,
726 mode_t mode,
727 uid_t uid,
728 gid_t gid,
729 char **tags) {
730
731 _cleanup_free_ char *unescaped_filename = NULL;
732 _cleanup_close_ int node_fd = -1;
733 const char *devnode;
734 struct stat stats;
735 int r;
736
737 assert(name);
738
739 if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags)
740 return 0;
741
742 devnode = strjoina("/dev/", name);
743
744 node_fd = open(devnode, O_PATH|O_CLOEXEC);
745 if (node_fd < 0) {
746 if (errno != ENOENT)
747 return log_error_errno(errno, "Failed to open %s: %m", devnode);
748 return 0;
749 }
750
751 if (fstat(node_fd, &stats) < 0)
752 return log_error_errno(errno, "Failed to stat %s: %m", devnode);
753
754 if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) {
755 log_warning("%s is neither block nor character device, ignoring.", devnode);
756 return 0;
757 }
758
759 if (!strv_isempty(tags)) {
760 unescaped_filename = xescape(name, "/.");
761 if (!unescaped_filename)
762 return log_oom();
763 }
764
765 /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
766 STRV_FOREACH(t, tags) {
767 _cleanup_free_ char *p = NULL;
768
769 p = path_join("/run/udev/static_node-tags/", *t, unescaped_filename);
770 if (!p)
771 return log_oom();
772
773 r = mkdir_parents(p, 0755);
774 if (r < 0)
775 return log_error_errno(r, "Failed to create parent directory for %s: %m", p);
776
777 r = symlink(devnode, p);
778 if (r < 0 && errno != EEXIST)
779 return log_error_errno(errno, "Failed to create symlink %s -> %s: %m", p, devnode);
780 }
781
782 return udev_node_apply_permissions_impl(NULL, node_fd, devnode, false, mode, uid, gid, NULL);
783 }