]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udev-node.c
tree-wide: use new RET_NERRNO() helper at various places
[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 "fd-util.h"
17 #include "format-util.h"
18 #include "fs-util.h"
19 #include "hexdecoct.h"
20 #include "mkdir.h"
21 #include "parse-util.h"
22 #include "path-util.h"
23 #include "random-util.h"
24 #include "selinux-util.h"
25 #include "smack-util.h"
26 #include "stat-util.h"
27 #include "stdio-util.h"
28 #include "string-util.h"
29 #include "strxcpyx.h"
30 #include "time-util.h"
31 #include "udev-node.h"
32 #include "user-util.h"
33
34 #define CREATE_LINK_MAX_RETRIES 128
35 #define LINK_UPDATE_MAX_RETRIES 128
36 #define CREATE_STACK_LINK_MAX_RETRIES 128
37 #define UPDATE_TIMESTAMP_MAX_RETRIES 128
38 #define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC)
39 #define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC)
40 #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f)
41
42 static int create_symlink(const char *target, const char *slink) {
43 int r;
44
45 assert(target);
46 assert(slink);
47
48 for (unsigned i = 0; i < CREATE_LINK_MAX_RETRIES; i++) {
49 r = mkdir_parents_label(slink, 0755);
50 if (r == -ENOENT)
51 continue;
52 if (r < 0)
53 return r;
54
55 mac_selinux_create_file_prepare(slink, S_IFLNK);
56 r = RET_NERRNO(symlink(target, slink));
57 mac_selinux_create_file_clear();
58 if (r != -ENOENT)
59 return r;
60 }
61
62 return r;
63 }
64
65 static int node_symlink(sd_device *dev, const char *node, const char *slink) {
66 _cleanup_free_ char *slink_dirname = NULL, *target = NULL;
67 const char *id, *slink_tmp;
68 struct stat stats;
69 int r;
70
71 assert(dev);
72 assert(node);
73 assert(slink);
74
75 if (lstat(slink, &stats) >= 0) {
76 if (!S_ISLNK(stats.st_mode))
77 return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST),
78 "Conflicting inode '%s' found, link to '%s' will not be created.", slink, node);
79 } else if (errno != ENOENT)
80 return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink);
81
82 r = path_extract_directory(slink, &slink_dirname);
83 if (r < 0)
84 return log_device_debug_errno(dev, r, "Failed to get parent directory of '%s': %m", slink);
85
86 /* use relative link */
87 r = path_make_relative(slink_dirname, node, &target);
88 if (r < 0)
89 return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, node);
90
91 r = device_get_device_id(dev, &id);
92 if (r < 0)
93 return log_device_debug_errno(dev, r, "Failed to get device id: %m");
94
95 slink_tmp = strjoina(slink, ".tmp-", id);
96 (void) unlink(slink_tmp);
97
98 r = create_symlink(target, slink_tmp);
99 if (r < 0)
100 return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target);
101
102 if (rename(slink_tmp, slink) < 0) {
103 r = log_device_debug_errno(dev, errno, "Failed to rename '%s' to '%s': %m", slink_tmp, slink);
104 (void) unlink(slink_tmp);
105 return r;
106 }
107
108 return 0;
109 }
110
111 static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) {
112 _cleanup_closedir_ DIR *dir = NULL;
113 _cleanup_free_ char *target = NULL;
114 struct dirent *dent;
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(dent, dir, break) {
157 _cleanup_free_ char *path = NULL, *buf = NULL;
158 int tmp_prio;
159
160 if (dent->d_name[0] == '.')
161 continue;
162
163 /* skip ourself */
164 if (streq(dent->d_name, id))
165 continue;
166
167 path = path_join(stackdir, dent->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, dent->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 int udev_node_apply_permissions(
595 sd_device *dev,
596 bool apply_mac,
597 mode_t mode,
598 uid_t uid,
599 gid_t gid,
600 OrderedHashmap *seclabel_list) {
601
602 const char *devnode, *subsystem, *id = NULL;
603 bool apply_mode, apply_uid, apply_gid;
604 _cleanup_close_ int node_fd = -1;
605 struct stat stats;
606 dev_t devnum;
607 int r;
608
609 assert(dev);
610
611 r = sd_device_get_devname(dev, &devnode);
612 if (r < 0)
613 return log_device_debug_errno(dev, r, "Failed to get devname: %m");
614 r = sd_device_get_subsystem(dev, &subsystem);
615 if (r < 0)
616 return log_device_debug_errno(dev, r, "Failed to get subsystem: %m");
617 r = sd_device_get_devnum(dev, &devnum);
618 if (r < 0)
619 return log_device_debug_errno(dev, r, "Failed to get devnum: %m");
620 (void) device_get_device_id(dev, &id);
621
622 if (streq(subsystem, "block"))
623 mode |= S_IFBLK;
624 else
625 mode |= S_IFCHR;
626
627 node_fd = open(devnode, O_PATH|O_NOFOLLOW|O_CLOEXEC);
628 if (node_fd < 0) {
629 if (errno == ENOENT) {
630 log_device_debug_errno(dev, errno, "Device node %s is missing, skipping handling.", devnode);
631 return 0; /* This is necessarily racey, so ignore missing the device */
632 }
633
634 return log_device_debug_errno(dev, errno, "Cannot open node %s: %m", devnode);
635 }
636
637 if (fstat(node_fd, &stats) < 0)
638 return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode);
639
640 if ((mode != MODE_INVALID && (stats.st_mode & S_IFMT) != (mode & S_IFMT)) || stats.st_rdev != devnum) {
641 log_device_debug(dev, "Found node '%s' with non-matching devnum %s, skipping handling.",
642 devnode, strna(id));
643 return 0; /* We might process a device that already got replaced by the time we have a look
644 * at it, handle this gracefully and step away. */
645 }
646
647 apply_mode = mode != MODE_INVALID && (stats.st_mode & 0777) != (mode & 0777);
648 apply_uid = uid_is_valid(uid) && stats.st_uid != uid;
649 apply_gid = gid_is_valid(gid) && stats.st_gid != gid;
650
651 if (apply_mode || apply_uid || apply_gid || apply_mac) {
652 bool selinux = false, smack = false;
653 const char *name, *label;
654
655 if (apply_mode || apply_uid || apply_gid) {
656 log_device_debug(dev, "Setting permissions %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o",
657 devnode,
658 uid_is_valid(uid) ? uid : stats.st_uid,
659 gid_is_valid(gid) ? gid : stats.st_gid,
660 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
661
662 r = fchmod_and_chown(node_fd, mode, uid, gid);
663 if (r < 0)
664 log_device_full_errno(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r,
665 "Failed to set owner/mode of %s to uid=" UID_FMT
666 ", gid=" GID_FMT ", mode=%#o: %m",
667 devnode,
668 uid_is_valid(uid) ? uid : stats.st_uid,
669 gid_is_valid(gid) ? gid : stats.st_gid,
670 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
671 } else
672 log_device_debug(dev, "Preserve permissions of %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o",
673 devnode,
674 uid_is_valid(uid) ? uid : stats.st_uid,
675 gid_is_valid(gid) ? gid : stats.st_gid,
676 mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
677
678 /* apply SECLABEL{$module}=$label */
679 ORDERED_HASHMAP_FOREACH_KEY(label, name, seclabel_list) {
680 int q;
681
682 if (streq(name, "selinux")) {
683 selinux = true;
684
685 q = mac_selinux_apply_fd(node_fd, devnode, label);
686 if (q < 0)
687 log_device_full_errno(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
688 "SECLABEL: failed to set SELinux label '%s': %m", label);
689 else
690 log_device_debug(dev, "SECLABEL: set SELinux label '%s'", label);
691
692 } else if (streq(name, "smack")) {
693 smack = true;
694
695 q = mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, label);
696 if (q < 0)
697 log_device_full_errno(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
698 "SECLABEL: failed to set SMACK label '%s': %m", label);
699 else
700 log_device_debug(dev, "SECLABEL: set SMACK label '%s'", label);
701
702 } else
703 log_device_error(dev, "SECLABEL: unknown subsystem, ignoring '%s'='%s'", name, label);
704 }
705
706 /* set the defaults */
707 if (!selinux)
708 (void) mac_selinux_fix_fd(node_fd, devnode, LABEL_IGNORE_ENOENT);
709 if (!smack)
710 (void) mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, NULL);
711 }
712
713 /* always update timestamp when we re-use the node, like on media change events */
714 r = futimens_opath(node_fd, NULL);
715 if (r < 0)
716 log_device_debug_errno(dev, r, "Failed to adjust timestamp of node %s: %m", devnode);
717
718 return 0;
719 }