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 *node
, const char *slink
) {
67 _cleanup_free_
char *slink_dirname
= NULL
, *target
= NULL
;
68 const char *id
, *slink_tmp
;
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
);
83 r
= path_extract_directory(slink
, &slink_dirname
);
85 return log_device_debug_errno(dev
, r
, "Failed to get parent directory of '%s': %m", slink
);
87 /* use relative link */
88 r
= path_make_relative(slink_dirname
, node
, &target
);
90 return log_device_debug_errno(dev
, r
, "Failed to get relative path from '%s' to '%s': %m", slink
, node
);
92 r
= device_get_device_id(dev
, &id
);
94 return log_device_debug_errno(dev
, r
, "Failed to get device id: %m");
96 slink_tmp
= strjoina(slink
, ".tmp-", id
);
97 (void) unlink(slink_tmp
);
99 r
= create_symlink(target
, slink_tmp
);
101 return log_device_debug_errno(dev
, r
, "Failed to create symlink '%s' to '%s': %m", slink_tmp
, target
);
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
);
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
;
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. */
128 r
= device_get_devlink_priority(dev
, &priority
);
132 r
= sd_device_get_devname(dev
, &devnode
);
136 target
= strdup(devnode
);
141 dir
= opendir(stackdir
);
145 r
= device_get_device_id(dev
, &id
);
149 FOREACH_DIRENT_ALL(de
, dir
, break) {
150 _cleanup_free_
char *path
= NULL
, *buf
= NULL
;
153 if (de
->d_name
[0] == '.')
157 if (streq(de
->d_name
, id
))
160 path
= path_join(stackdir
, de
->d_name
);
164 if (readlink_malloc(path
, &buf
) >= 0) {
167 /* New format. The devnode and priority can be obtained from symlink. */
169 devnode
= strchr(buf
, ':');
170 if (!devnode
|| devnode
== buf
)
174 if (!path_startswith(devnode
, "/dev"))
177 if (safe_atoi(buf
, &tmp_prio
) < 0)
180 if (target
&& tmp_prio
<= priority
)
183 r
= free_and_strdup(&target
, devnode
);
187 _cleanup_(sd_device_unrefp
) sd_device
*tmp_dev
= NULL
;
190 /* Old format. The devnode and priority must be obtained from uevent and
191 * udev database files. */
193 if (sd_device_new_from_device_id(&tmp_dev
, de
->d_name
) < 0)
196 if (device_get_devlink_priority(tmp_dev
, &tmp_prio
) < 0)
199 if (target
&& tmp_prio
<= priority
)
202 if (sd_device_get_devname(tmp_dev
, &devnode
) < 0)
205 r
= free_and_strdup(&target
, devnode
);
213 *ret
= TAKE_PTR(target
);
217 static int update_timestamp(sd_device
*dev
, int fd
, struct stat
*prev
) {
221 /* Even if a symlink in the stack directory is created/removed, the mtime of the directory may
222 * not be changed. Why? Let's consider the following situation. For simplicity, let's assume
223 * there exist two udev workers (A and B) and all of them calls link_update() for the same
224 * devlink simultaneously.
226 * 1. A creates/removes a symlink in the stack directory.
227 * 2. A calls the first stat() in the loop of link_update().
228 * 3. A calls link_find_prioritized().
229 * 4. B creates/removes another symlink in the stack directory, so the result of the step 3 is outdated.
230 * 5. B finishes link_update().
231 * 6. A creates/removes devlink according to the outdated result in the step 3.
232 * 7. A calls the second stat() in the loop of link_update().
234 * If these 7 steps are processed in this order within a short time period that kernel's timer
235 * does not increase, then even if the contents in the stack directory is changed, the results
236 * of two stat() called by A shows the same timestamp, and A cannot detect the change.
238 * By calling this function after creating/removing symlinks in the stack directory, the
239 * timestamp of the stack directory is always increased at least in the above step 5, so A can
240 * detect the update. */
242 for (unsigned i
= 0; i
< UPDATE_TIMESTAMP_MAX_RETRIES
; i
++) {
245 if (fstat(fd
, &st
) < 0)
248 if (!stat_inode_unmodified(prev
, &st
))
251 log_device_debug(dev
,
252 "Stack directory is modified, but its timestamp is not changed, "
253 "updating timestamp after 10ms.");
255 (void) usleep(10 * USEC_PER_MSEC
);
256 if (futimens(fd
, NULL
) < 0)
263 static int stack_directory_update(sd_device
*dev
, int fd
, bool add
) {
271 r
= device_get_device_id(dev
, &id
);
275 if (fstat(fd
, &st
) < 0)
279 _cleanup_free_
char *data
= NULL
, *buf
= NULL
;
283 r
= sd_device_get_devname(dev
, &devname
);
287 r
= device_get_devlink_priority(dev
, &priority
);
291 if (asprintf(&data
, "%i:%s", priority
, devname
) < 0)
294 if (readlinkat_malloc(fd
, id
, &buf
) >= 0 && streq(buf
, data
))
295 return 0; /* Unchanged. */
297 (void) unlinkat(fd
, id
, 0);
299 if (symlinkat(data
, fd
, id
) < 0)
303 if (unlinkat(fd
, id
, 0) < 0) {
305 return 0; /* Unchanged. */
310 r
= update_timestamp(dev
, fd
, &st
);
317 static int stack_directory_open(const char *dirname
) {
318 _cleanup_close_
int fd
= -1;
323 r
= mkdir_parents(dirname
, 0755);
327 fd
= open_mkdir_at(AT_FDCWD
, dirname
, O_CLOEXEC
| O_DIRECTORY
| O_NOFOLLOW
| O_RDONLY
, 0755);
334 size_t udev_node_escape_path(const char *src
, char *dest
, size_t size
) {
342 for (i
= 0, j
= 0; src
[i
] != '\0'; i
++) {
344 if (j
+4 >= size
- 12 + 1)
346 memcpy(&dest
[j
], "\\x2f", 4);
348 } else if (src
[i
] == '\\') {
349 if (j
+4 >= size
- 12 + 1)
351 memcpy(&dest
[j
], "\\x5c", 4);
354 if (j
+1 >= size
- 12 + 1)
364 /* If the input path is too long to encode as a filename, then let's suffix with a string
365 * generated from the hash of the path. */
367 h
= siphash24_string(src
, UDEV_NODE_HASH_KEY
.bytes
);
369 for (unsigned k
= 0; k
<= 10; k
++)
370 dest
[size
- k
- 2] = urlsafe_base64char((h
>> (k
* 6)) & 63);
372 dest
[size
- 1] = '\0';
376 static int stack_directory_get_name(const char *slink
, char **ret
) {
377 _cleanup_free_
char *s
= NULL
, *dirname
= NULL
;
378 char name_enc
[NAME_MAX
+1];
390 if (!path_is_normalized(s
))
393 name
= path_startswith(s
, "/dev");
394 if (empty_or_root(name
))
397 udev_node_escape_path(name
, name_enc
, sizeof(name_enc
));
399 dirname
= path_join("/run/udev/links", name_enc
);
403 *ret
= TAKE_PTR(dirname
);
407 static int link_update(sd_device
*dev
, const char *slink
, bool add
) {
408 _cleanup_free_
char *dirname
= NULL
;
409 _cleanup_close_
int dirfd
= -1;
415 r
= stack_directory_get_name(slink
, &dirname
);
417 return log_device_debug_errno(dev
, r
, "Failed to build stack directory name for '%s': %m", slink
);
419 dirfd
= stack_directory_open(dirname
);
421 return log_device_debug_errno(dev
, dirfd
, "Failed to open stack directory '%s': %m", dirname
);
423 r
= stack_directory_update(dev
, dirfd
, add
);
425 return log_device_debug_errno(dev
, r
, "Failed to update stack directory '%s': %m", dirname
);
427 for (unsigned i
= 0; i
< LINK_UPDATE_MAX_RETRIES
; i
++) {
428 _cleanup_free_
char *target
= NULL
;
429 struct stat st1
= {}, st2
= {};
432 usec_t delay
= MIN_RANDOM_DELAY
+ random_u64_range(MAX_RANDOM_DELAY
- MIN_RANDOM_DELAY
);
434 log_device_debug(dev
, "Directory %s was updated, retrying to update devlink %s after %s.",
435 dirname
, slink
, FORMAT_TIMESPAN(delay
, USEC_PER_MSEC
));
436 (void) usleep(delay
);
439 if (stat(dirname
, &st1
) < 0 && errno
!= ENOENT
)
440 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
442 r
= link_find_prioritized(dev
, add
, dirname
, &target
);
444 return log_device_debug_errno(dev
, r
, "Failed to determine device node with the highest priority for '%s': %m", slink
);
446 log_device_debug(dev
, "No reference left for '%s', removing", slink
);
448 if (unlink(slink
) < 0 && errno
!= ENOENT
)
449 log_device_debug_errno(dev
, errno
, "Failed to remove '%s', ignoring: %m", slink
);
451 (void) rmdir_parents(slink
, "/dev");
455 r
= node_symlink(dev
, target
, slink
);
459 if (stat(dirname
, &st2
) < 0 && errno
!= ENOENT
)
460 return log_device_debug_errno(dev
, errno
, "Failed to stat %s: %m", dirname
);
462 if (((st1
.st_mode
& S_IFMT
) == 0 && (st2
.st_mode
& S_IFMT
) == 0) ||
463 stat_inode_unmodified(&st1
, &st2
))
470 static int device_get_devpath_by_devnum(sd_device
*dev
, char **ret
) {
471 const char *subsystem
;
478 r
= sd_device_get_subsystem(dev
, &subsystem
);
482 r
= sd_device_get_devnum(dev
, &devnum
);
486 return device_path_make_major_minor(streq(subsystem
, "block") ? S_IFBLK
: S_IFCHR
, devnum
, ret
);
489 int udev_node_update(sd_device
*dev
, sd_device
*dev_old
) {
490 _cleanup_free_
char *filename
= NULL
;
491 const char *devnode
, *devlink
;
497 r
= sd_device_get_devname(dev
, &devnode
);
499 return log_device_debug_errno(dev
, r
, "Failed to get devnode: %m");
502 const char *id
= NULL
;
504 (void) device_get_device_id(dev
, &id
);
505 log_device_debug(dev
, "Handling device node '%s', devnum=%s", devnode
, strna(id
));
508 /* update possible left-over symlinks */
509 FOREACH_DEVICE_DEVLINK(dev_old
, devlink
) {
510 /* check if old link name still belongs to this device */
511 if (device_has_devlink(dev
, devlink
))
514 log_device_debug(dev
,
515 "Removing/updating old device symlink '%s', which is no longer belonging to this device.",
518 r
= link_update(dev
, devlink
, /* add = */ false);
520 log_device_warning_errno(dev
, r
,
521 "Failed to remove/update device symlink '%s', ignoring: %m",
525 /* create/update symlinks, add symlinks to name index */
526 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
527 r
= link_update(dev
, devlink
, /* add = */ true);
529 log_device_warning_errno(dev
, r
,
530 "Failed to create/update device symlink '%s', ignoring: %m",
534 r
= device_get_devpath_by_devnum(dev
, &filename
);
536 return log_device_debug_errno(dev
, r
, "Failed to get device path: %m");
538 /* always add /dev/{block,char}/$major:$minor */
539 r
= node_symlink(dev
, devnode
, filename
);
541 return log_device_warning_errno(dev
, r
, "Failed to create device symlink '%s': %m", filename
);
546 int udev_node_remove(sd_device
*dev
) {
547 _cleanup_free_
char *filename
= NULL
;
553 /* remove/update symlinks, remove symlinks from name index */
554 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
555 r
= link_update(dev
, devlink
, /* add = */ false);
557 log_device_warning_errno(dev
, r
,
558 "Failed to remove/update device symlink '%s', ignoring: %m",
562 r
= device_get_devpath_by_devnum(dev
, &filename
);
564 return log_device_debug_errno(dev
, r
, "Failed to get device path: %m");
566 /* remove /dev/{block,char}/$major:$minor */
567 if (unlink(filename
) < 0 && errno
!= ENOENT
)
568 return log_device_debug_errno(dev
, errno
, "Failed to remove '%s': %m", filename
);
573 static int udev_node_apply_permissions_impl(
574 sd_device
*dev
, /* can be NULL, only used for logging. */
581 OrderedHashmap
*seclabel_list
) {
583 bool apply_mode
, apply_uid
, apply_gid
;
587 assert(node_fd
>= 0);
590 if (fstat(node_fd
, &stats
) < 0)
591 return log_device_debug_errno(dev
, errno
, "cannot stat() node %s: %m", devnode
);
593 /* If group is set, but mode is not set, "upgrade" mode for the group. */
594 if (mode
== MODE_INVALID
&& gid_is_valid(gid
) && gid
> 0)
597 apply_mode
= mode
!= MODE_INVALID
&& (stats
.st_mode
& 0777) != (mode
& 0777);
598 apply_uid
= uid_is_valid(uid
) && stats
.st_uid
!= uid
;
599 apply_gid
= gid_is_valid(gid
) && stats
.st_gid
!= gid
;
601 if (apply_mode
|| apply_uid
|| apply_gid
|| apply_mac
) {
602 bool selinux
= false, smack
= false;
603 const char *name
, *label
;
605 if (apply_mode
|| apply_uid
|| apply_gid
) {
606 log_device_debug(dev
, "Setting permissions %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
608 uid_is_valid(uid
) ? uid
: stats
.st_uid
,
609 gid_is_valid(gid
) ? gid
: stats
.st_gid
,
610 mode
!= MODE_INVALID
? mode
& 0777 : stats
.st_mode
& 0777);
612 r
= fchmod_and_chown(node_fd
, mode
, uid
, gid
);
614 log_device_full_errno(dev
, r
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, r
,
615 "Failed to set owner/mode of %s to uid=" UID_FMT
616 ", gid=" GID_FMT
", mode=%#o: %m",
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 log_device_debug(dev
, "Preserve permissions of %s, uid=" UID_FMT
", gid=" GID_FMT
", mode=%#o",
624 uid_is_valid(uid
) ? uid
: stats
.st_uid
,
625 gid_is_valid(gid
) ? gid
: stats
.st_gid
,
626 mode
!= MODE_INVALID
? mode
& 0777 : stats
.st_mode
& 0777);
628 /* apply SECLABEL{$module}=$label */
629 ORDERED_HASHMAP_FOREACH_KEY(label
, name
, seclabel_list
) {
632 if (streq(name
, "selinux")) {
635 q
= mac_selinux_apply_fd(node_fd
, devnode
, label
);
637 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
638 "SECLABEL: failed to set SELinux label '%s': %m", label
);
640 log_device_debug(dev
, "SECLABEL: set SELinux label '%s'", label
);
642 } else if (streq(name
, "smack")) {
645 q
= mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, label
);
647 log_device_full_errno(dev
, q
== -ENOENT
? LOG_DEBUG
: LOG_ERR
, q
,
648 "SECLABEL: failed to set SMACK label '%s': %m", label
);
650 log_device_debug(dev
, "SECLABEL: set SMACK label '%s'", label
);
653 log_device_error(dev
, "SECLABEL: unknown subsystem, ignoring '%s'='%s'", name
, label
);
656 /* set the defaults */
658 (void) mac_selinux_fix_full(node_fd
, NULL
, devnode
, LABEL_IGNORE_ENOENT
);
660 (void) mac_smack_apply_fd(node_fd
, SMACK_ATTR_ACCESS
, NULL
);
663 /* always update timestamp when we re-use the node, like on media change events */
664 r
= futimens_opath(node_fd
, NULL
);
666 log_device_debug_errno(dev
, r
, "Failed to adjust timestamp of node %s: %m", devnode
);
671 int udev_node_apply_permissions(
677 OrderedHashmap
*seclabel_list
) {
680 _cleanup_close_
int node_fd
= -1;
685 r
= sd_device_get_devname(dev
, &devnode
);
687 return log_device_debug_errno(dev
, r
, "Failed to get devname: %m");
689 node_fd
= sd_device_open(dev
, O_PATH
|O_CLOEXEC
);
691 if (ERRNO_IS_DEVICE_ABSENT(node_fd
)) {
692 log_device_debug_errno(dev
, node_fd
, "Device node %s is missing, skipping handling.", devnode
);
693 return 0; /* This is necessarily racey, so ignore missing the device */
696 return log_device_debug_errno(dev
, node_fd
, "Cannot open node %s: %m", devnode
);
699 return udev_node_apply_permissions_impl(dev
, node_fd
, devnode
, apply_mac
, mode
, uid
, gid
, seclabel_list
);
702 int static_node_apply_permissions(
709 _cleanup_free_
char *unescaped_filename
= NULL
;
710 _cleanup_close_
int node_fd
= -1;
717 if (uid
== UID_INVALID
&& gid
== GID_INVALID
&& mode
== MODE_INVALID
&& !tags
)
720 devnode
= strjoina("/dev/", name
);
722 node_fd
= open(devnode
, O_PATH
|O_CLOEXEC
);
725 return log_error_errno(errno
, "Failed to open %s: %m", devnode
);
729 if (fstat(node_fd
, &stats
) < 0)
730 return log_error_errno(errno
, "Failed to stat %s: %m", devnode
);
732 if (!S_ISBLK(stats
.st_mode
) && !S_ISCHR(stats
.st_mode
)) {
733 log_warning("%s is neither block nor character device, ignoring.", devnode
);
737 if (!strv_isempty(tags
)) {
738 unescaped_filename
= xescape(name
, "/.");
739 if (!unescaped_filename
)
743 /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
744 STRV_FOREACH(t
, tags
) {
745 _cleanup_free_
char *p
= NULL
;
747 p
= path_join("/run/udev/static_node-tags/", *t
, unescaped_filename
);
751 r
= mkdir_parents(p
, 0755);
753 return log_error_errno(r
, "Failed to create parent directory for %s: %m", p
);
755 r
= symlink(devnode
, p
);
756 if (r
< 0 && errno
!= EEXIST
)
757 return log_error_errno(errno
, "Failed to create symlink %s -> %s: %m", p
, devnode
);
760 return udev_node_apply_permissions_impl(NULL
, node_fd
, devnode
, false, mode
, uid
, gid
, NULL
);