1 /* SPDX-License-Identifier: GPL-2.0-or-later */
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"
19 #include "format-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"
32 #include "time-util.h"
33 #include "udev-node.h"
34 #include "user-util.h"
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)
44 static int create_symlink(const char *target
, const char *slink
) {
50 for (unsigned i
= 0; i
< CREATE_LINK_MAX_RETRIES
; i
++) {
51 r
= mkdir_parents_label(slink
, 0755);
57 mac_selinux_create_file_prepare(slink
, S_IFLNK
);
58 r
= RET_NERRNO(symlink(target
, slink
));
59 mac_selinux_create_file_clear();
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
;
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
);
84 r
= path_extract_directory(slink
, &slink_dirname
);
86 return log_device_debug_errno(dev
, r
, "Failed to get parent directory of '%s': %m", slink
);
88 /* use relative link */
89 r
= path_make_relative(slink_dirname
, node
, &target
);
91 return log_device_debug_errno(dev
, r
, "Failed to get relative path from '%s' to '%s': %m", slink
, node
);
93 r
= device_get_device_id(dev
, &id
);
95 return log_device_debug_errno(dev
, r
, "Failed to get device id: %m");
97 slink_tmp
= strjoina(slink
, ".tmp-", id
);
98 (void) unlink(slink_tmp
);
100 r
= create_symlink(target
, slink_tmp
);
102 return log_device_debug_errno(dev
, r
, "Failed to create symlink '%s' to '%s': %m", slink_tmp
, target
);
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
);
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
;
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. */
129 r
= device_get_devlink_priority(dev
, &priority
);
133 r
= sd_device_get_devname(dev
, &devnode
);
137 target
= strdup(devnode
);
142 dir
= opendir(stackdir
);
144 if (add
) /* The stack directory must exist. */
153 r
= device_get_device_id(dev
, &id
);
157 FOREACH_DIRENT_ALL(de
, dir
, break) {
158 _cleanup_free_
char *path
= NULL
, *buf
= NULL
;
161 if (de
->d_name
[0] == '.')
165 if (streq(de
->d_name
, id
))
168 path
= path_join(stackdir
, de
->d_name
);
172 if (readlink_malloc(path
, &buf
) >= 0) {
175 /* New format. The devnode and priority can be obtained from symlink. */
177 devnode
= strchr(buf
, ':');
178 if (!devnode
|| devnode
== buf
)
182 if (!path_startswith(devnode
, "/dev"))
185 if (safe_atoi(buf
, &tmp_prio
) < 0)
188 if (target
&& tmp_prio
<= priority
)
191 r
= free_and_strdup(&target
, devnode
);
195 _cleanup_(sd_device_unrefp
) sd_device
*tmp_dev
= NULL
;
198 /* Old format. The devnode and priority must be obtained from uevent and
199 * udev database files. */
201 if (sd_device_new_from_device_id(&tmp_dev
, de
->d_name
) < 0)
204 if (device_get_devlink_priority(tmp_dev
, &tmp_prio
) < 0)
207 if (target
&& tmp_prio
<= priority
)
210 if (sd_device_get_devname(tmp_dev
, &devnode
) < 0)
213 r
= free_and_strdup(&target
, devnode
);
221 *ret
= TAKE_PTR(target
);
225 size_t udev_node_escape_path(const char *src
, char *dest
, size_t size
) {
233 for (i
= 0, j
= 0; src
[i
] != '\0'; i
++) {
235 if (j
+4 >= size
- 12 + 1)
237 memcpy(&dest
[j
], "\\x2f", 4);
239 } else if (src
[i
] == '\\') {
240 if (j
+4 >= size
- 12 + 1)
242 memcpy(&dest
[j
], "\\x5c", 4);
245 if (j
+1 >= size
- 12 + 1)
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. */
258 h
= siphash24_string(src
, UDEV_NODE_HASH_KEY
.bytes
);
260 for (unsigned k
= 0; k
<= 10; k
++)
261 dest
[size
- k
- 2] = urlsafe_base64char((h
>> (k
* 6)) & 63);
263 dest
[size
- 1] = '\0';
267 static int update_timestamp(sd_device
*dev
, const char *path
, struct stat
*prev
) {
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.
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().
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.
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. */
292 if ((prev
->st_mode
& S_IFMT
) == 0)
293 return 0; /* Does not exist, or previous stat() failed. */
295 for (unsigned i
= 0; i
< UPDATE_TIMESTAMP_MAX_RETRIES
; i
++) {
298 if (stat(path
, &st
) < 0)
301 if (!stat_inode_unmodified(prev
, &st
))
304 log_device_debug(dev
,
305 "%s is modified, but its timestamp is not changed, "
306 "updating timestamp after 10ms.",
309 (void) usleep(10 * USEC_PER_MSEC
);
310 if (utimensat(AT_FDCWD
, path
, NULL
, 0) < 0)
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
;
326 r
= device_get_device_id(dev
, &id
);
328 return log_device_debug_errno(dev
, r
, "Failed to get device id: %m");
330 filename
= path_join(dirname
, id
);
332 return log_oom_debug();
335 int unlink_error
= 0, stat_error
= 0;
337 if (stat(dirname
, &st
) < 0) {
339 return 0; /* The stack directory is already removed. That's OK. */
343 if (unlink(filename
) < 0)
344 unlink_error
= -errno
;
346 if (rmdir(dirname
) >= 0 || errno
== ENOENT
)
349 if (unlink_error
< 0) {
350 if (unlink_error
== -ENOENT
)
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
);
358 return log_device_debug_errno(dev
, stat_error
, "Failed to stat %s: %m", dirname
);
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
);
368 r
= sd_device_get_devname(dev
, &devname
);
370 return log_device_debug_errno(dev
, r
, "Failed to get device node: %m");
372 r
= device_get_devlink_priority(dev
, &priority
);
374 return log_device_debug_errno(dev
, r
, "Failed to get priority of device node symlink: %m");
376 if (asprintf(&data
, "%i:%s", priority
, devname
) < 0)
377 return log_oom_debug();
379 if (readlink_malloc(filename
, &buf
) >= 0 && streq(buf
, data
))
382 if (unlink(filename
) < 0 && errno
!= ENOENT
)
383 log_device_debug_errno(dev
, errno
, "Failed to remove %s, ignoring: %m", filename
);
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);
392 return log_device_debug_errno(dev
, r
, "Failed to create directory %s: %m", dirname
);
394 if (stat(dirname
, &st
) < 0) {
397 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
400 if (symlink(data
, filename
) < 0) {
403 return log_device_debug_errno(dev
, errno
, "Failed to create symbolic link %s: %m", filename
);
406 /* The symlink was created. Check if the timestamp of directory is changed. */
407 r
= update_timestamp(dev
, dirname
, &st
);
409 return log_device_debug_errno(dev
, r
, "Failed to update timestamp of %s: %m", dirname
);
414 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ELOOP
), "Failed to create symbolic link %s: %m", filename
);
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];
427 slink
= strdup(slink_in
);
429 return log_oom_debug();
431 path_simplify(slink
);
433 slink_name
= path_startswith(slink
, "/dev");
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
);
440 (void) udev_node_escape_path(slink_name
, name_enc
, sizeof(name_enc
));
441 dirname
= path_join("/run/udev/links", name_enc
);
443 return log_oom_debug();
445 r
= update_stack_directory(dev
, dirname
, add
);
449 for (unsigned i
= 0; i
< LINK_UPDATE_MAX_RETRIES
; i
++) {
450 _cleanup_free_
char *target
= NULL
;
451 struct stat st1
= {}, st2
= {};
454 usec_t delay
= MIN_RANDOM_DELAY
+ random_u64_range(MAX_RANDOM_DELAY
- MIN_RANDOM_DELAY
);
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
);
461 if (stat(dirname
, &st1
) < 0 && errno
!= ENOENT
)
462 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
464 r
= link_find_prioritized(dev
, add
, dirname
, &target
);
466 return log_device_debug_errno(dev
, r
, "Failed to determine device node with the highest priority for '%s': %m", slink
);
468 log_device_debug(dev
, "No reference left for '%s', removing", slink
);
470 if (unlink(slink
) < 0 && errno
!= ENOENT
)
471 log_device_debug_errno(dev
, errno
, "Failed to remove '%s', ignoring: %m", slink
);
473 (void) rmdir_parents(slink
, "/dev");
477 r
= node_symlink(dev
, target
, slink
);
481 if (stat(dirname
, &st2
) < 0 && errno
!= ENOENT
)
482 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
484 if (((st1
.st_mode
& S_IFMT
) == 0 && (st2
.st_mode
& S_IFMT
) == 0) ||
485 stat_inode_unmodified(&st1
, &st2
))
492 static int device_get_devpath_by_devnum(sd_device
*dev
, char **ret
) {
493 const char *subsystem
;
500 r
= sd_device_get_subsystem(dev
, &subsystem
);
504 r
= sd_device_get_devnum(dev
, &devnum
);
508 return device_path_make_major_minor(streq(subsystem
, "block") ? S_IFBLK
: S_IFCHR
, devnum
, ret
);
511 int udev_node_update(sd_device
*dev
, sd_device
*dev_old
) {
512 _cleanup_free_
char *filename
= NULL
;
513 const char *devnode
, *devlink
;
519 r
= sd_device_get_devname(dev
, &devnode
);
521 return log_device_debug_errno(dev
, r
, "Failed to get devnode: %m");
524 const char *id
= NULL
;
526 (void) device_get_device_id(dev
, &id
);
527 log_device_debug(dev
, "Handling device node '%s', devnum=%s", devnode
, strna(id
));
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
))
536 log_device_debug(dev
,
537 "Removing/updating old device symlink '%s', which is no longer belonging to this device.",
540 r
= link_update(dev
, devlink
, /* add = */ false);
542 log_device_warning_errno(dev
, r
,
543 "Failed to remove/update device symlink '%s', ignoring: %m",
547 /* create/update symlinks, add symlinks to name index */
548 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
549 r
= link_update(dev
, devlink
, /* add = */ true);
551 log_device_warning_errno(dev
, r
,
552 "Failed to create/update device symlink '%s', ignoring: %m",
556 r
= device_get_devpath_by_devnum(dev
, &filename
);
558 return log_device_debug_errno(dev
, r
, "Failed to get device path: %m");
560 /* always add /dev/{block,char}/$major:$minor */
561 r
= node_symlink(dev
, devnode
, filename
);
563 return log_device_warning_errno(dev
, r
, "Failed to create device symlink '%s': %m", filename
);
568 int udev_node_remove(sd_device
*dev
) {
569 _cleanup_free_
char *filename
= NULL
;
575 /* remove/update symlinks, remove symlinks from name index */
576 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
577 r
= link_update(dev
, devlink
, /* add = */ false);
579 log_device_warning_errno(dev
, r
,
580 "Failed to remove/update device symlink '%s', ignoring: %m",
584 r
= device_get_devpath_by_devnum(dev
, &filename
);
586 return log_device_debug_errno(dev
, r
, "Failed to get device path: %m");
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
);
595 static int udev_node_apply_permissions_impl(
596 sd_device
*dev
, /* can be NULL, only used for logging. */
603 OrderedHashmap
*seclabel_list
) {
605 bool apply_mode
, apply_uid
, apply_gid
;
609 assert(node_fd
>= 0);
612 if (fstat(node_fd
, &stats
) < 0)
613 return log_device_debug_errno(dev
, errno
, "cannot stat() node %s: %m", devnode
);
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)
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
;
623 if (apply_mode
|| apply_uid
|| apply_gid
|| apply_mac
) {
624 bool selinux
= false, smack
= false;
625 const char *name
, *label
;
627 if (apply_mode
|| apply_uid
|| apply_gid
) {
628 log_device_debug(dev
, "Setting permissions %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
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);
634 r
= fchmod_and_chown(node_fd
, mode
, uid
, gid
);
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",
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);
644 log_device_debug(dev
, "Preserve permissions of %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
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);
650 /* apply SECLABEL{$module}=$label */
651 ORDERED_HASHMAP_FOREACH_KEY(label
, name
, seclabel_list
) {
654 if (streq(name
, "selinux")) {
657 q
= mac_selinux_apply_fd(node_fd
, devnode
, label
);
659 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
660 "SECLABEL: failed to set SELinux label '%s': %m", label
);
662 log_device_debug(dev
, "SECLABEL: set SELinux label '%s'", label
);
664 } else if (streq(name
, "smack")) {
667 q
= mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, label
);
669 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
670 "SECLABEL: failed to set SMACK label '%s': %m", label
);
672 log_device_debug(dev
, "SECLABEL: set SMACK label '%s'", label
);
675 log_device_error(dev
, "SECLABEL: unknown subsystem, ignoring '%s'='%s'", name
, label
);
678 /* set the defaults */
680 (void) mac_selinux_fix_full(node_fd
, NULL
, devnode
, LABEL_IGNORE_ENOENT
);
682 (void) mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, NULL
);
685 /* always update timestamp when we re-use the node, like on media change events */
686 r
= futimens_opath(node_fd
, NULL
);
688 log_device_debug_errno(dev
, r
, "Failed to adjust timestamp of node %s: %m", devnode
);
693 int udev_node_apply_permissions(
699 OrderedHashmap
*seclabel_list
) {
702 _cleanup_close_
int node_fd
= -1;
707 r
= sd_device_get_devname(dev
, &devnode
);
709 return log_device_debug_errno(dev
, r
, "Failed to get devname: %m");
711 node_fd
= sd_device_open(dev
, O_PATH
|O_CLOEXEC
);
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 */
718 return log_device_debug_errno(dev
, node_fd
, "Cannot open node %s: %m", devnode
);
721 return udev_node_apply_permissions_impl(dev
, node_fd
, devnode
, apply_mac
, mode
, uid
, gid
, seclabel_list
);
724 int static_node_apply_permissions(
731 _cleanup_free_
char *unescaped_filename
= NULL
;
732 _cleanup_close_
int node_fd
= -1;
739 if (uid
== UID_INVALID
&& gid
== GID_INVALID
&& mode
== MODE_INVALID
&& !tags
)
742 devnode
= strjoina("/dev/", name
);
744 node_fd
= open(devnode
, O_PATH
|O_CLOEXEC
);
747 return log_error_errno(errno
, "Failed to open %s: %m", devnode
);
751 if (fstat(node_fd
, &stats
) < 0)
752 return log_error_errno(errno
, "Failed to stat %s: %m", devnode
);
754 if (!S_ISBLK(stats
.st_mode
) && !S_ISCHR(stats
.st_mode
)) {
755 log_warning("%s is neither block nor character device, ignoring.", devnode
);
759 if (!strv_isempty(tags
)) {
760 unescaped_filename
= xescape(name
, "/.");
761 if (!unescaped_filename
)
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
;
769 p
= path_join("/run/udev/static_node-tags/", *t
, unescaped_filename
);
773 r
= mkdir_parents(p
, 0755);
775 return log_error_errno(r
, "Failed to create parent directory for %s: %m", p
);
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
);
782 return udev_node_apply_permissions_impl(NULL
, node_fd
, devnode
, false, mode
, uid
, gid
, NULL
);