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 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)
43 static int create_symlink(const char *target
, const char *slink
) {
49 for (unsigned i
= 0; i
< CREATE_LINK_MAX_RETRIES
; i
++) {
50 r
= mkdir_parents_label(slink
, 0755);
56 mac_selinux_create_file_prepare(slink
, S_IFLNK
);
57 r
= RET_NERRNO(symlink(target
, slink
));
58 mac_selinux_create_file_clear();
66 static int node_symlink(sd_device
*dev
, const char *devnode
, const char *slink
) {
67 _cleanup_free_
char *target
= NULL
;
68 const char *id
, *slink_tmp
;
76 r
= sd_device_get_devname(dev
, &devnode
);
78 return log_device_debug_errno(dev
, r
, "Failed to get device node: %m");
81 if (lstat(slink
, &st
) >= 0) {
82 if (!S_ISLNK(st
.st_mode
))
83 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EEXIST
),
84 "Conflicting inode '%s' found, symlink to '%s' will not be created.",
86 } else if (errno
!= ENOENT
)
87 return log_device_debug_errno(dev
, errno
, "Failed to lstat() '%s': %m", slink
);
89 /* use relative link */
90 r
= path_make_relative_parent(slink
, devnode
, &target
);
92 return log_device_debug_errno(dev
, r
, "Failed to get relative path from '%s' to '%s': %m", slink
, devnode
);
94 r
= device_get_device_id(dev
, &id
);
96 return log_device_debug_errno(dev
, r
, "Failed to get device id: %m");
98 slink_tmp
= strjoina(slink
, ".tmp-", id
);
99 (void) unlink(slink_tmp
);
101 r
= create_symlink(target
, slink_tmp
);
103 return log_device_debug_errno(dev
, r
, "Failed to create symlink '%s' to '%s': %m", slink_tmp
, target
);
105 if (rename(slink_tmp
, slink
) < 0) {
106 r
= log_device_debug_errno(dev
, errno
, "Failed to rename '%s' to '%s': %m", slink_tmp
, slink
);
107 (void) unlink(slink_tmp
);
114 static int stack_directory_find_prioritized_devnode(sd_device
*dev
, const char *dirname
, bool add
, char **ret
) {
115 _cleanup_closedir_
DIR *dir
= NULL
;
116 _cleanup_free_
char *devnode
= NULL
;
124 /* Find device node of device with highest priority. This returns 1 if a device found, 0 if no
125 * device found, or a negative errno on error. */
130 r
= device_get_devlink_priority(dev
, &priority
);
134 r
= sd_device_get_devname(dev
, &n
);
143 dir
= opendir(dirname
);
147 r
= device_get_device_id(dev
, &id
);
151 FOREACH_DIRENT_ALL(de
, dir
, break) {
154 if (de
->d_name
[0] == '.')
158 if (streq(de
->d_name
, id
))
161 if (de
->d_type
== DT_LNK
) {
162 _cleanup_free_
char *buf
= NULL
;
165 /* New format. The devnode and priority can be obtained from symlink. */
167 r
= readlinkat_malloc(dirfd(dir
), de
->d_name
, &buf
);
169 log_device_debug_errno(dev
, r
, "Failed to read symlink %s, ignoring: %m", de
->d_name
);
173 colon
= strchr(buf
, ':');
174 if (!colon
|| colon
== buf
)
179 if (safe_atoi(buf
, &tmp_prio
) < 0)
182 if (devnode
&& tmp_prio
<= priority
)
185 r
= free_and_strdup(&devnode
, colon
+ 1);
189 } else if (de
->d_type
== DT_REG
) {
190 _cleanup_(sd_device_unrefp
) sd_device
*tmp_dev
= NULL
;
193 /* Old format. The devnode and priority must be obtained from uevent and
194 * udev database files. */
196 if (sd_device_new_from_device_id(&tmp_dev
, de
->d_name
) < 0)
199 if (device_get_devlink_priority(tmp_dev
, &tmp_prio
) < 0)
202 if (devnode
&& tmp_prio
<= priority
)
205 if (sd_device_get_devname(tmp_dev
, &val
) < 0)
208 r
= free_and_strdup(&devnode
, val
);
218 *ret
= TAKE_PTR(devnode
);
222 static int update_timestamp(sd_device
*dev
, int fd
, struct stat
*prev
) {
226 /* Even if a symlink in the stack directory is created/removed, the mtime of the directory may
227 * not be changed. Why? Let's consider the following situation. For simplicity, let's assume
228 * there exist two udev workers (A and B) and all of them calls link_update() for the same
229 * devlink simultaneously.
231 * 1. A creates/removes a symlink in the stack directory.
232 * 2. A calls the first stat() in the loop of link_update().
233 * 3. A calls link_find_prioritized().
234 * 4. B creates/removes another symlink in the stack directory, so the result of the step 3 is outdated.
235 * 5. B finishes link_update().
236 * 6. A creates/removes devlink according to the outdated result in the step 3.
237 * 7. A calls the second stat() in the loop of link_update().
239 * If these 7 steps are processed in this order within a short time period that kernel's timer
240 * does not increase, then even if the contents in the stack directory is changed, the results
241 * of two stat() called by A shows the same timestamp, and A cannot detect the change.
243 * By calling this function after creating/removing symlinks in the stack directory, the
244 * timestamp of the stack directory is always increased at least in the above step 5, so A can
245 * detect the update. */
247 for (unsigned i
= 0; i
< UPDATE_TIMESTAMP_MAX_RETRIES
; i
++) {
250 if (fstat(fd
, &st
) < 0)
253 if (!stat_inode_unmodified(prev
, &st
))
256 log_device_debug(dev
,
257 "Stack directory is modified, but its timestamp is not changed, "
258 "updating timestamp after 10ms.");
260 (void) usleep(10 * USEC_PER_MSEC
);
261 if (futimens(fd
, NULL
) < 0)
268 static int stack_directory_update(sd_device
*dev
, int fd
, bool add
) {
276 r
= device_get_device_id(dev
, &id
);
280 if (fstat(fd
, &st
) < 0)
284 _cleanup_free_
char *data
= NULL
, *buf
= NULL
;
288 r
= sd_device_get_devname(dev
, &devname
);
292 r
= device_get_devlink_priority(dev
, &priority
);
296 if (asprintf(&data
, "%i:%s", priority
, devname
) < 0)
299 if (readlinkat_malloc(fd
, id
, &buf
) >= 0 && streq(buf
, data
))
300 return 0; /* Unchanged. */
302 (void) unlinkat(fd
, id
, 0);
304 if (symlinkat(data
, fd
, id
) < 0)
308 if (unlinkat(fd
, id
, 0) < 0) {
310 return 0; /* Unchanged. */
315 r
= update_timestamp(dev
, fd
, &st
);
322 static int stack_directory_open(const char *dirname
) {
323 _cleanup_close_
int fd
= -1;
328 r
= mkdir_parents(dirname
, 0755);
332 fd
= open_mkdir_at(AT_FDCWD
, dirname
, O_CLOEXEC
| O_DIRECTORY
| O_NOFOLLOW
| O_RDONLY
, 0755);
339 size_t udev_node_escape_path(const char *src
, char *dest
, size_t size
) {
347 for (i
= 0, j
= 0; src
[i
] != '\0'; i
++) {
349 if (j
+4 >= size
- 12 + 1)
351 memcpy(&dest
[j
], "\\x2f", 4);
353 } else if (src
[i
] == '\\') {
354 if (j
+4 >= size
- 12 + 1)
356 memcpy(&dest
[j
], "\\x5c", 4);
359 if (j
+1 >= size
- 12 + 1)
369 /* If the input path is too long to encode as a filename, then let's suffix with a string
370 * generated from the hash of the path. */
372 h
= siphash24_string(src
, UDEV_NODE_HASH_KEY
.bytes
);
374 for (unsigned k
= 0; k
<= 10; k
++)
375 dest
[size
- k
- 2] = urlsafe_base64char((h
>> (k
* 6)) & 63);
377 dest
[size
- 1] = '\0';
381 static int stack_directory_get_name(const char *slink
, char **ret
) {
382 _cleanup_free_
char *s
= NULL
, *dirname
= NULL
;
383 char name_enc
[NAME_MAX
+1];
395 if (!path_is_normalized(s
))
398 name
= path_startswith(s
, "/dev");
399 if (empty_or_root(name
))
402 udev_node_escape_path(name
, name_enc
, sizeof(name_enc
));
404 dirname
= path_join("/run/udev/links", name_enc
);
408 *ret
= TAKE_PTR(dirname
);
412 static int link_update(sd_device
*dev
, const char *slink
, bool add
) {
413 _cleanup_free_
char *dirname
= NULL
;
414 _cleanup_close_
int dirfd
= -1;
420 r
= stack_directory_get_name(slink
, &dirname
);
422 return log_device_debug_errno(dev
, r
, "Failed to build stack directory name for '%s': %m", slink
);
424 dirfd
= stack_directory_open(dirname
);
426 return log_device_debug_errno(dev
, dirfd
, "Failed to open stack directory '%s': %m", dirname
);
428 r
= stack_directory_update(dev
, dirfd
, add
);
430 return log_device_debug_errno(dev
, r
, "Failed to update stack directory '%s': %m", dirname
);
432 for (unsigned i
= 0; i
< LINK_UPDATE_MAX_RETRIES
; i
++) {
433 _cleanup_free_
char *target
= NULL
;
434 struct stat st1
= {}, st2
= {};
437 usec_t delay
= MIN_RANDOM_DELAY
+ random_u64_range(MAX_RANDOM_DELAY
- MIN_RANDOM_DELAY
);
439 log_device_debug(dev
, "Directory %s was updated, retrying to update devlink %s after %s.",
440 dirname
, slink
, FORMAT_TIMESPAN(delay
, USEC_PER_MSEC
));
441 (void) usleep(delay
);
444 if (stat(dirname
, &st1
) < 0 && errno
!= ENOENT
)
445 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
447 r
= stack_directory_find_prioritized_devnode(dev
, dirname
, add
, &target
);
449 return log_device_debug_errno(dev
, r
, "Failed to determine device node with the highest priority for '%s': %m", slink
);
451 log_device_debug(dev
, "No reference left for '%s', removing", slink
);
453 if (unlink(slink
) < 0 && errno
!= ENOENT
)
454 log_device_debug_errno(dev
, errno
, "Failed to remove '%s', ignoring: %m", slink
);
456 (void) rmdir_parents(slink
, "/dev");
460 r
= node_symlink(dev
, target
, slink
);
464 if (stat(dirname
, &st2
) < 0 && errno
!= ENOENT
)
465 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
467 if (((st1
.st_mode
& S_IFMT
) == 0 && (st2
.st_mode
& S_IFMT
) == 0) ||
468 stat_inode_unmodified(&st1
, &st2
))
475 static int device_get_devpath_by_devnum(sd_device
*dev
, char **ret
) {
476 const char *subsystem
;
483 r
= sd_device_get_subsystem(dev
, &subsystem
);
487 r
= sd_device_get_devnum(dev
, &devnum
);
491 return device_path_make_major_minor(streq(subsystem
, "block") ? S_IFBLK
: S_IFCHR
, devnum
, ret
);
494 int udev_node_update(sd_device
*dev
, sd_device
*dev_old
) {
495 _cleanup_free_
char *filename
= NULL
;
502 /* update possible left-over symlinks */
503 FOREACH_DEVICE_DEVLINK(dev_old
, devlink
) {
504 /* check if old link name still belongs to this device */
505 if (device_has_devlink(dev
, devlink
))
508 log_device_debug(dev
,
509 "Removing/updating old device symlink '%s', which is no longer belonging to this device.",
512 r
= link_update(dev
, devlink
, /* add = */ false);
514 log_device_warning_errno(dev
, r
,
515 "Failed to remove/update device symlink '%s', ignoring: %m",
519 /* create/update symlinks, add symlinks to name index */
520 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
521 r
= link_update(dev
, devlink
, /* add = */ true);
523 log_device_warning_errno(dev
, r
,
524 "Failed to create/update device symlink '%s', ignoring: %m",
528 r
= device_get_devpath_by_devnum(dev
, &filename
);
530 return log_device_debug_errno(dev
, r
, "Failed to get device path: %m");
532 /* always add /dev/{block,char}/$major:$minor */
533 r
= node_symlink(dev
, NULL
, filename
);
535 return log_device_warning_errno(dev
, r
, "Failed to create device symlink '%s': %m", filename
);
540 int udev_node_remove(sd_device
*dev
) {
541 _cleanup_free_
char *filename
= NULL
;
547 /* remove/update symlinks, remove symlinks from name index */
548 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
549 r
= link_update(dev
, devlink
, /* add = */ false);
551 log_device_warning_errno(dev
, r
,
552 "Failed to remove/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 /* remove /dev/{block,char}/$major:$minor */
561 if (unlink(filename
) < 0 && errno
!= ENOENT
)
562 return log_device_debug_errno(dev
, errno
, "Failed to remove '%s': %m", filename
);
567 static int udev_node_apply_permissions_impl(
568 sd_device
*dev
, /* can be NULL, only used for logging. */
575 OrderedHashmap
*seclabel_list
) {
577 bool apply_mode
, apply_uid
, apply_gid
;
581 assert(node_fd
>= 0);
584 if (fstat(node_fd
, &stats
) < 0)
585 return log_device_debug_errno(dev
, errno
, "cannot stat() node %s: %m", devnode
);
587 /* If group is set, but mode is not set, "upgrade" mode for the group. */
588 if (mode
== MODE_INVALID
&& gid_is_valid(gid
) && gid
> 0)
591 apply_mode
= mode
!= MODE_INVALID
&& (stats
.st_mode
& 0777) != (mode
& 0777);
592 apply_uid
= uid_is_valid(uid
) && stats
.st_uid
!= uid
;
593 apply_gid
= gid_is_valid(gid
) && stats
.st_gid
!= gid
;
595 if (apply_mode
|| apply_uid
|| apply_gid
|| apply_mac
) {
596 bool selinux
= false, smack
= false;
597 const char *name
, *label
;
599 if (apply_mode
|| apply_uid
|| apply_gid
) {
600 log_device_debug(dev
, "Setting permissions %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
602 uid_is_valid(uid
) ? uid
: stats
.st_uid
,
603 gid_is_valid(gid
) ? gid
: stats
.st_gid
,
604 mode
!= MODE_INVALID
? mode
& 0777 : stats
.st_mode
& 0777);
606 r
= fchmod_and_chown(node_fd
, mode
, uid
, gid
);
608 log_device_full_errno(dev
, r
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, r
,
609 "Failed to set owner/mode of %s to uid=" UID_FMT
610 ", gid=" GID_FMT
", mode=%#o: %m",
612 uid_is_valid(uid
) ? uid
: stats
.st_uid
,
613 gid_is_valid(gid
) ? gid
: stats
.st_gid
,
614 mode
!= MODE_INVALID
? mode
& 0777 : stats
.st_mode
& 0777);
616 log_device_debug(dev
, "Preserve permissions of %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
618 uid_is_valid(uid
) ? uid
: stats
.st_uid
,
619 gid_is_valid(gid
) ? gid
: stats
.st_gid
,
620 mode
!= MODE_INVALID
? mode
& 0777 : stats
.st_mode
& 0777);
622 /* apply SECLABEL{$module}=$label */
623 ORDERED_HASHMAP_FOREACH_KEY(label
, name
, seclabel_list
) {
626 if (streq(name
, "selinux")) {
629 q
= mac_selinux_apply_fd(node_fd
, devnode
, label
);
631 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
632 "SECLABEL: failed to set SELinux label '%s': %m", label
);
634 log_device_debug(dev
, "SECLABEL: set SELinux label '%s'", label
);
636 } else if (streq(name
, "smack")) {
639 q
= mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, label
);
641 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
642 "SECLABEL: failed to set SMACK label '%s': %m", label
);
644 log_device_debug(dev
, "SECLABEL: set SMACK label '%s'", label
);
647 log_device_error(dev
, "SECLABEL: unknown subsystem, ignoring '%s'='%s'", name
, label
);
650 /* set the defaults */
652 (void) mac_selinux_fix_full(node_fd
, NULL
, devnode
, LABEL_IGNORE_ENOENT
);
654 (void) mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, NULL
);
657 /* always update timestamp when we re-use the node, like on media change events */
658 r
= futimens_opath(node_fd
, NULL
);
660 log_device_debug_errno(dev
, r
, "Failed to adjust timestamp of node %s: %m", devnode
);
665 int udev_node_apply_permissions(
671 OrderedHashmap
*seclabel_list
) {
674 _cleanup_close_
int node_fd
= -1;
679 r
= sd_device_get_devname(dev
, &devnode
);
681 return log_device_debug_errno(dev
, r
, "Failed to get devname: %m");
683 node_fd
= sd_device_open(dev
, O_PATH
|O_CLOEXEC
);
685 if (ERRNO_IS_DEVICE_ABSENT(node_fd
)) {
686 log_device_debug_errno(dev
, node_fd
, "Device node %s is missing, skipping handling.", devnode
);
687 return 0; /* This is necessarily racey, so ignore missing the device */
690 return log_device_debug_errno(dev
, node_fd
, "Cannot open node %s: %m", devnode
);
693 return udev_node_apply_permissions_impl(dev
, node_fd
, devnode
, apply_mac
, mode
, uid
, gid
, seclabel_list
);
696 int static_node_apply_permissions(
703 _cleanup_free_
char *unescaped_filename
= NULL
;
704 _cleanup_close_
int node_fd
= -1;
711 if (uid
== UID_INVALID
&& gid
== GID_INVALID
&& mode
== MODE_INVALID
&& !tags
)
714 devnode
= strjoina("/dev/", name
);
716 node_fd
= open(devnode
, O_PATH
|O_CLOEXEC
);
719 return log_error_errno(errno
, "Failed to open %s: %m", devnode
);
723 if (fstat(node_fd
, &stats
) < 0)
724 return log_error_errno(errno
, "Failed to stat %s: %m", devnode
);
726 if (!S_ISBLK(stats
.st_mode
) && !S_ISCHR(stats
.st_mode
)) {
727 log_warning("%s is neither block nor character device, ignoring.", devnode
);
731 if (!strv_isempty(tags
)) {
732 unescaped_filename
= xescape(name
, "/.");
733 if (!unescaped_filename
)
737 /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
738 STRV_FOREACH(t
, tags
) {
739 _cleanup_free_
char *p
= NULL
;
741 p
= path_join("/run/udev/static_node-tags/", *t
, unescaped_filename
);
745 r
= mkdir_parents(p
, 0755);
747 return log_error_errno(r
, "Failed to create parent directory for %s: %m", p
);
749 r
= symlink(devnode
, p
);
750 if (r
< 0 && errno
!= EEXIST
)
751 return log_error_errno(errno
, "Failed to create symlink %s -> %s: %m", p
, devnode
);
754 return udev_node_apply_permissions_impl(NULL
, node_fd
, devnode
, false, mode
, uid
, gid
, NULL
);