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