• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14939761809

09 May 2025 06:22PM UTC coverage: 72.251% (-0.001%) from 72.252%
14939761809

push

github

web-flow
mount-tool: honor arg_canonicalize for ACTION_UMOUNT path_is_absolute() check too (#37398)

Split out from #36337

4 of 4 new or added lines in 2 files covered. (100.0%)

3591 existing lines in 114 files now uncovered.

297546 of 411820 relevant lines covered (72.25%)

704170.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/src/shared/dev-setup.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <errno.h>
4
#include <stdlib.h>
5
#include <sys/sysmacros.h>
6
#include <unistd.h>
7

8
#include "alloc-util.h"
9
#include "dev-setup.h"
10
#include "fd-util.h"
11
#include "fs-util.h"
12
#include "label-util.h"
13
#include "lock-util.h"
14
#include "log.h"
15
#include "mkdir-label.h"
16
#include "nulstr-util.h"
17
#include "path-util.h"
18
#include "stat-util.h"
19
#include "terminal-util.h"
20
#include "umask-util.h"
21
#include "user-util.h"
22

23
int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
954✔
24
        static const char symlinks[] =
954✔
25
                "-/proc/kcore\0"     "/dev/core\0"
26
                "/proc/self/fd\0"    "/dev/fd\0"
27
                "/proc/self/fd/0\0"  "/dev/stdin\0"
28
                "/proc/self/fd/1\0"  "/dev/stdout\0"
29
                "/proc/self/fd/2\0"  "/dev/stderr\0";
30

31
        int r;
954✔
32

33
        NULSTR_FOREACH_PAIR(j, k, symlinks) {
10,494✔
34
                _cleanup_free_ char *link_name = NULL;
4,770✔
35
                const char *n;
4,770✔
36

37
                if (j[0] == '-') {
4,770✔
38
                        j++;
954✔
39

40
                        if (access(j, F_OK) < 0)
954✔
UNCOV
41
                                continue;
×
42
                }
43

44
                if (prefix) {
4,770✔
45
                        link_name = path_join(prefix, k);
4,470✔
46
                        if (!link_name)
4,470✔
UNCOV
47
                                return -ENOMEM;
×
48

49
                        n = link_name;
50
                } else
51
                        n = k;
52

53
                r = symlink_label(j, n);
4,770✔
54
                if (r < 0)
4,770✔
55
                        log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n);
240✔
56

57
                if (uid != UID_INVALID || gid != GID_INVALID)
4,770✔
58
                        if (lchown(n, uid, gid) < 0)
1,090✔
59
                                log_debug_errno(errno, "Failed to chown %s: %m", n);
4,770✔
60
        }
61

62
        return 0;
63
}
64

65
int make_inaccessible_nodes(
413✔
66
                const char *parent_dir,
67
                uid_t uid,
68
                gid_t gid) {
69

70
        static const mode_t table[] = {
413✔
71
                S_IFREG,
72
                S_IFDIR,
73
                S_IFIFO,
74
                S_IFSOCK,
75

76
                /* The following two are likely to fail if we lack the privs for it (for example in an userns
77
                 * environment, if CAP_SYS_MKNOD is missing, or if a device node policy prohibits creation of
78
                 * device nodes with a major/minor of 0). But that's entirely fine. Consumers of these files
79
                 * should implement falling back to use a different node then, for example
80
                 * <root>/inaccessible/sock, which is close enough in behaviour and semantics for most uses.
81
                 */
82
                S_IFCHR,
83
                S_IFBLK,
84

85
                /* NB: S_IFLNK is not listed here, as there is no such thing as an inaccessible symlink */
86
        };
87

88
        _cleanup_close_ int parent_fd = -EBADF, inaccessible_fd = -EBADF;
413✔
89
        int r;
413✔
90

91
        if (!parent_dir)
413✔
UNCOV
92
                parent_dir = "/run/systemd";
×
93

94
        BLOCK_WITH_UMASK(0000);
826✔
95

96
        parent_fd = open(parent_dir, O_DIRECTORY|O_CLOEXEC|O_PATH, 0);
413✔
97
        if (parent_fd < 0)
413✔
UNCOV
98
                return -errno;
×
99

100
        inaccessible_fd = open_mkdir_at_full(parent_fd, "inaccessible", O_CLOEXEC, XO_LABEL, 0755);
413✔
101
        if (inaccessible_fd < 0)
413✔
102
                return inaccessible_fd;
103

104
        /* Set up inaccessible (and empty) file nodes of all types. This are used to as mount sources for over-mounting
105
         * ("masking") file nodes that shall become inaccessible and empty for specific containers or services. We try
106
         * to lock down these nodes as much as we can, but otherwise try to match them as closely as possible with the
107
         * underlying file, i.e. in the best case we offer the same node type as the underlying node. */
108

109
        FOREACH_ELEMENT(m, table) {
2,891✔
110
                _cleanup_free_ char *path = NULL;
2,478✔
111
                mode_t inode_type = *m;
2,478✔
112
                const char *fn;
2,478✔
113

114
                fn = inode_type_to_string(inode_type);
2,478✔
115
                path = path_join(parent_dir, fn);
2,478✔
116
                if (!path)
2,478✔
UNCOV
117
                        return log_oom();
×
118

119
                if (S_ISDIR(inode_type))
2,478✔
120
                        r = mkdirat_label(inaccessible_fd, fn, 0000);
413✔
121
                else
122
                        r = mknodat_label(inaccessible_fd, fn, inode_type | 0000, makedev(0, 0));
2,065✔
123
                if (r == -EEXIST) {
2,478✔
124
                        if (fchmodat(inaccessible_fd, fn, 0000, AT_SYMLINK_NOFOLLOW) < 0)
64✔
UNCOV
125
                                log_debug_errno(errno, "Failed to adjust access mode of existing inode '%s', ignoring: %m", path);
×
126
                } else if (r < 0) {
2,414✔
127
                        log_debug_errno(r, "Failed to create '%s', ignoring: %m", path);
122✔
128
                        continue;
122✔
129
                }
130

131
                if (uid_is_valid(uid) || gid_is_valid(gid))
3,400✔
132
                        if (fchownat(inaccessible_fd, fn, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
1,312✔
133
                                log_debug_errno(errno, "Failed to chown '%s', ignoring: %m", path);
2,356✔
134
        }
135

136
        if (fchmod(inaccessible_fd, 0555) < 0)
413✔
137
                log_debug_errno(errno, "Failed to mark inaccessible directory read-only, ignoring: %m");
413✔
138

139
        return 0;
140
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc