Skip to content

Commit

Permalink
udev-node: use symlink_atomic_full_label() to create devlink
Browse files Browse the repository at this point in the history
If the filename of a device symlink is too long, then the temporary
filename may become invalid, and we fail to create symlink.

The function `tempfn_random()` used in symlink_atomic_full() generates
a safe temporary filename.

Note that, thanks to the PR systemd#23043, now only one worker can handle
the same symlink simultaneously. Hence, the device ID based temporary
filename is not necessary.
  • Loading branch information
yuwata committed Sep 18, 2022
1 parent 2591979 commit 87d4783
Showing 1 changed file with 7 additions and 26 deletions.
33 changes: 7 additions & 26 deletions src/udev/udev-node.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "format-util.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "label.h"
#include "mkdir-label.h"
#include "parse-util.h"
#include "path-util.h"
Expand Down Expand Up @@ -69,8 +70,6 @@ int udev_node_cleanup(void) {
}

static int node_symlink(sd_device *dev, const char *devnode, const char *slink) {
_cleanup_free_ char *target = NULL;
const char *id, *slink_tmp;
struct stat st;
int r;

Expand All @@ -91,34 +90,16 @@ static int node_symlink(sd_device *dev, const char *devnode, const char *slink)
} else if (errno != ENOENT)
return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink);

/* use relative link */
r = path_make_relative_parent(slink, devnode, &target);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, devnode);

r = device_get_device_id(dev, &id);
r = mkdir_parents_label(slink, 0755);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get device id: %m");

slink_tmp = strjoina(slink, ".tmp-", id);
(void) unlink(slink_tmp);
return log_device_debug_errno(dev, r, "Failed to create parent directory of '%s': %m", slink);

r = mkdir_parents_label(slink_tmp, 0755);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to create parent directory of '%s': %m", slink_tmp);

mac_selinux_create_file_prepare(slink_tmp, S_IFLNK);
r = RET_NERRNO(symlink(target, slink_tmp));
mac_selinux_create_file_clear();
/* use relative link */
r = symlink_atomic_full_label(devnode, slink, /* make_relative = */ true);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target);

if (rename(slink_tmp, slink) < 0) {
r = log_device_debug_errno(dev, errno, "Failed to rename '%s' to '%s': %m", slink_tmp, slink);
(void) unlink(slink_tmp);
return r;
}
return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink, devnode);

log_device_debug(dev, "Successfully created symlink '%s' to '%s'", slink, devnode);
return 0;
}

Expand Down

0 comments on commit 87d4783

Please sign in to comment.