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

systemd / systemd / 15837872256

23 Jun 2025 09:28PM UTC coverage: 72.09% (-0.02%) from 72.105%
15837872256

push

github

bluca
test-cpu-set-util: fix check for CPUSet.allocated

The check was simply wrong and meaningless, as it always checked
CPUSet.allocated is greater than or equals to 1, as sizeof(__cpu_mask) is 8.

Let's make the test more strict.

300458 of 416781 relevant lines covered (72.09%)

709101.32 hits per line

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

93.39
/src/basic/hostname-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <stdlib.h>
4

5
#include "alloc-util.h"
6
#include "env-file.h"
7
#include "hostname-util.h"
8
#include "log.h"
9
#include "os-util.h"
10
#include "string-util.h"
11
#include "strv.h"
12
#include "user-util.h"
13

14
char* get_default_hostname_raw(void) {
46✔
15
        int r;
46✔
16

17
        /* Returns the default hostname, and leaves any ??? in place. */
18

19
        const char *e = secure_getenv("SYSTEMD_DEFAULT_HOSTNAME");
46✔
20
        if (e) {
46✔
21
                if (hostname_is_valid(e, VALID_HOSTNAME_QUESTION_MARK))
×
22
                        return strdup(e);
46✔
23

24
                log_debug("Invalid hostname in $SYSTEMD_DEFAULT_HOSTNAME, ignoring: %s", e);
×
25
        }
26

27
        _cleanup_free_ char *f = NULL;
46✔
28
        r = parse_os_release(NULL, "DEFAULT_HOSTNAME", &f);
46✔
29
        if (r < 0)
46✔
30
                log_debug_errno(r, "Failed to parse os-release, ignoring: %m");
×
31
        else if (f) {
46✔
32
                if (hostname_is_valid(f, VALID_HOSTNAME_QUESTION_MARK))
×
33
                        return TAKE_PTR(f);
×
34

35
                log_debug("Invalid hostname in os-release, ignoring: %s", f);
×
36
        }
37

38
        return strdup(FALLBACK_HOSTNAME);
46✔
39
}
40

41
bool valid_ldh_char(char c) {
76,500✔
42
        /* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */
43

44
        return ascii_isalpha(c) ||
76,500✔
45
                ascii_isdigit(c) ||
76,500✔
46
                c == '-';
47
}
48

49
bool hostname_is_valid(const char *s, ValidHostnameFlags flags) {
4,190✔
50
        unsigned n_dots = 0;
4,190✔
51
        const char *p;
4,190✔
52
        bool dot, hyphen;
4,190✔
53

54
        /* Check if s looks like a valid hostname or FQDN. This does not do full DNS validation, but only
55
         * checks if the name is composed of allowed characters and the length is not above the maximum
56
         * allowed by Linux (c.f. dns_name_is_valid()). A trailing dot is allowed if
57
         * VALID_HOSTNAME_TRAILING_DOT flag is set and at least two components are present in the name. Note
58
         * that due to the restricted charset and length this call is substantially more conservative than
59
         * dns_name_is_valid(). Doesn't accept empty hostnames, hostnames with leading dots, and hostnames
60
         * with multiple dots in a sequence. Doesn't allow hyphens at the beginning or end of label. */
61

62
        if (isempty(s))
4,190✔
63
                return false;
64

65
        if (streq(s, ".host")) /* Used by the container logic to denote the "root container" */
4,182✔
66
                return FLAGS_SET(flags, VALID_HOSTNAME_DOT_HOST);
113✔
67

68
        for (p = s, dot = hyphen = true; *p; p++)
79,926✔
69
                if (*p == '.') {
75,897✔
70
                        if (dot || hyphen)
11,616✔
71
                                return false;
72

73
                        dot = true;
11,604✔
74
                        hyphen = false;
11,604✔
75
                        n_dots++;
11,604✔
76

77
                } else if (*p == '-') {
64,281✔
78
                        if (dot)
2,253✔
79
                                return false;
80

81
                        dot = false;
82
                        hyphen = true;
83

84
                } else {
85
                        if (!valid_ldh_char(*p) && (*p != '?' || !FLAGS_SET(flags, VALID_HOSTNAME_QUESTION_MARK)))
62,028✔
86
                                return false;
87

88
                        dot = false;
89
                        hyphen = false;
90
                }
91

92
        if (dot && (n_dots < 2 || !FLAGS_SET(flags, VALID_HOSTNAME_TRAILING_DOT)))
4,029✔
93
                return false;
94
        if (hyphen)
4,023✔
95
                return false;
96

97
        if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to
4,023✔
98
                                  * 255 characters */
99
                return false;
5✔
100

101
        return true;
102
}
103

104
char* hostname_cleanup(char *s) {
413✔
105
        char *p, *d;
413✔
106
        bool dot, hyphen;
413✔
107

108
        assert(s);
413✔
109

110
        for (p = s, d = s, dot = hyphen = true; *p && d - s < HOST_NAME_MAX; p++)
13,382✔
111
                if (*p == '.') {
12,969✔
112
                        if (dot || hyphen)
741✔
113
                                continue;
16✔
114

115
                        *(d++) = '.';
725✔
116
                        dot = true;
725✔
117
                        hyphen = false;
725✔
118

119
                } else if (*p == '-') {
12,228✔
120
                        if (dot)
1,459✔
121
                                continue;
4✔
122

123
                        *(d++) = '-';
1,455✔
124
                        dot = false;
1,455✔
125
                        hyphen = true;
1,455✔
126

127
                } else if (valid_ldh_char(*p) || *p == '?') {
10,769✔
128
                        *(d++) = *p;
10,745✔
129
                        dot = false;
10,745✔
130
                        hyphen = false;
10,745✔
131
                }
132

133
        if (d > s && IN_SET(d[-1], '-', '.'))
413✔
134
                /* The dot can occur at most once, but we might have multiple
135
                 * hyphens, hence the loop */
136
                d--;
7✔
137
        *d = 0;
413✔
138

139
        return s;
413✔
140
}
141

142
bool is_localhost(const char *hostname) {
142,604✔
143
        assert(hostname);
142,604✔
144

145
        /* This tries to identify local host and domain names
146
         * described in RFC6761 plus the redhatism of localdomain */
147

148
        return STRCASE_IN_SET(
142,604✔
149
                        hostname,
150
                        "localhost",
151
                        "localhost.",
152
                        "localhost.localdomain",
153
                        "localhost.localdomain.") ||
142,301✔
154
                endswith_no_case(hostname, ".localhost") ||
284,572✔
155
                endswith_no_case(hostname, ".localhost.") ||
284,512✔
156
                endswith_no_case(hostname, ".localhost.localdomain") ||
427,056✔
157
                endswith_no_case(hostname, ".localhost.localdomain.");
142,211✔
158
}
159

160
const char* etc_hostname(void) {
543✔
161
        static const char *cached = NULL;
543✔
162

163
        if (!cached)
543✔
164
                cached = secure_getenv("SYSTEMD_ETC_HOSTNAME") ?: "/etc/hostname";
299✔
165

166
        return cached;
543✔
167
}
168

169
const char* etc_machine_info(void) {
205✔
170
        static const char *cached = NULL;
205✔
171

172
        if (!cached)
205✔
173
                cached = secure_getenv("SYSTEMD_ETC_MACHINE_INFO") ?: "/etc/machine-info";
33✔
174

175
        return cached;
205✔
176
}
177

178
int get_pretty_hostname(char **ret) {
12✔
179
        _cleanup_free_ char *n = NULL;
12✔
180
        int r;
12✔
181

182
        assert(ret);
12✔
183

184
        r = parse_env_file(NULL, etc_machine_info(), "PRETTY_HOSTNAME", &n);
12✔
185
        if (r < 0)
12✔
186
                return r;
187

188
        if (isempty(n))
12✔
189
                return -ENXIO;
190

191
        *ret = TAKE_PTR(n);
×
192
        return 0;
×
193
}
194

195
int split_user_at_host(const char *s, char **ret_user, char **ret_host) {
239✔
196
        _cleanup_free_ char *u = NULL, *h = NULL;
478✔
197

198
        /* Splits a user@host expression (one of those we accept on --machine= and similar). Returns NULL in
199
         * each of the two return parameters if that part was left empty. */
200

201
        assert(s);
239✔
202

203
        const char *rhs = strchr(s, '@');
239✔
204
        if (rhs) {
239✔
205
                if (ret_user && rhs > s) {
192✔
206
                        u = strndup(s, rhs - s);
183✔
207
                        if (!u)
183✔
208
                                return -ENOMEM;
209
                }
210

211
                if (ret_host && rhs[1] != 0) {
192✔
212
                        h = strdup(rhs + 1);
145✔
213
                        if (!h)
145✔
214
                                return -ENOMEM;
215
                }
216

217
        } else {
218
                if (isempty(s))
47✔
219
                        return -EINVAL;
220

221
                if (ret_host) {
45✔
222
                        h = strdup(s);
44✔
223
                        if (!h)
44✔
224
                                return -ENOMEM;
225
                }
226
        }
227

228
        if (ret_user)
237✔
229
                *ret_user = TAKE_PTR(u);
230✔
230
        if (ret_host)
237✔
231
                *ret_host = TAKE_PTR(h);
231✔
232

233
        return !!rhs; /* return > 0 if '@' was specified, 0 otherwise */
237✔
234
}
235

236
int machine_spec_valid(const char *s) {
146✔
237
        _cleanup_free_ char *u = NULL, *h = NULL;
146✔
238
        int r;
146✔
239

240
        assert(s);
146✔
241

242
        r = split_user_at_host(s, &u, &h);
146✔
243
        if (r == -EINVAL)
146✔
244
                return false;
245
        if (r < 0)
145✔
246
                return r;
247

248
        if (u && !valid_user_group_name(u, VALID_USER_RELAX | VALID_USER_ALLOW_NUMERIC))
145✔
249
                return false;
250

251
        if (h && !hostname_is_valid(h, VALID_HOSTNAME_DOT_HOST))
145✔
252
                return false;
2✔
253

254
        return true;
255
}
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