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

systemd / systemd / 16062852561

03 Jul 2025 10:04PM UTC coverage: 72.193% (+0.1%) from 72.096%
16062852561

push

github

bluca
pcrlock: process components outside of location window properly

So far, when we tried to match a component to eent log entries we
skipped those components if they were outside of our location window.
That however is too aggressive, since it means any components that are
already in the logs, but outside of the location window will be
considered unrecognized in the logs, and thus removed from the PCR
policy.

Change things around: always try to match up all components, regardless
if inside the location window or outside, but then make it non-fatal we
can't find a component outside of the location window.

Fixes: #36079

7 of 9 new or added lines in 1 file covered. (77.78%)

4116 existing lines in 75 files now uncovered.

301219 of 417241 relevant lines covered (72.19%)

730820.5 hits per line

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

25.0
/src/ssh-generator/ssh-proxy.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "sd-varlink.h"
6

7
#include "alloc-util.h"
8
#include "fd-util.h"
9
#include "io-util.h"
10
#include "iovec-util.h"
11
#include "log.h"
12
#include "main-func.h"
13
#include "socket-util.h"
14
#include "string-util.h"
15
#include "strv.h"
16
#include "varlink-util.h"
17

UNCOV
18
static int process_vsock_cid(unsigned cid, const char *port) {
×
19
        int r;
×
20

UNCOV
21
        assert(cid != VMADDR_CID_ANY);
×
22
        assert(port);
×
23

UNCOV
24
        union sockaddr_union sa = {
×
25
                .vm.svm_cid = cid,
26
                .vm.svm_family = AF_VSOCK,
27
        };
28

UNCOV
29
        r = vsock_parse_port(port, &sa.vm.svm_port);
×
30
        if (r < 0)
×
31
                return log_error_errno(r, "Failed to parse vsock port: %s", port);
×
32

UNCOV
33
        _cleanup_close_ int fd = socket(AF_VSOCK, SOCK_STREAM|SOCK_CLOEXEC, 0);
×
34
        if (fd < 0)
×
35
                return log_error_errno(errno, "Failed to allocate AF_VSOCK socket: %m");
×
36

UNCOV
37
        if (connect(fd, &sa.sa, sockaddr_len(&sa)) < 0)
×
38
                return log_error_errno(errno, "Failed to connect to vsock:%u:%u: %m", sa.vm.svm_cid, sa.vm.svm_port);
×
39

40
        /* OpenSSH wants us to send a single byte along with the file descriptor, hence do so */
UNCOV
41
        r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* iovlen= */ 1, /* flags= */ 0);
×
42
        if (r < 0)
×
43
                return log_error_errno(r, "Failed to send socket via STDOUT: %m");
×
44

UNCOV
45
        log_debug("Successfully sent AF_VSOCK socket via STDOUT.");
×
46
        return 0;
47
}
48

UNCOV
49
static int process_vsock_string(const char *host, const char *port) {
×
50
        unsigned cid;
×
51
        int r;
×
52

UNCOV
53
        assert(host);
×
54
        assert(port);
×
55

UNCOV
56
        r = vsock_parse_cid(host, &cid);
×
57
        if (r < 0)
×
58
                return log_error_errno(r, "Failed to parse vsock cid: %s", host);
×
59

UNCOV
60
        return process_vsock_cid(cid, port);
×
61
}
62

63
static int process_unix(const char *path) {
3✔
64
        int r;
3✔
65

66
        assert(path);
3✔
67

68
        /* We assume the path is absolute unless it starts with a dot (or is already explicitly absolute) */
69
        _cleanup_free_ char *prefixed = NULL;
3✔
70
        if (!STARTSWITH_SET(path, "/", "./")) {
3✔
71
                prefixed = strjoin("/", path);
3✔
72
                if (!prefixed)
3✔
UNCOV
73
                        return log_oom();
×
74

75
                path = prefixed;
76
        }
77

78
        _cleanup_close_ int fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
6✔
79
        if (fd < 0)
3✔
UNCOV
80
                return log_error_errno(errno, "Failed to allocate AF_UNIX socket: %m");
×
81

82
        r = connect_unix_path(fd, AT_FDCWD, path);
3✔
83
        if (r < 0)
3✔
UNCOV
84
                return log_error_errno(r, "Failed to connect to AF_UNIX socket %s: %m", path);
×
85

86
        r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* iovlen= */ 1, /* flags= */ 0);
3✔
87
        if (r < 0)
3✔
UNCOV
88
                return log_error_errno(r, "Failed to send socket via STDOUT: %m");
×
89

90
        log_debug("Successfully sent AF_UNIX socket via STDOUT.");
3✔
91
        return 0;
92
}
93

UNCOV
94
static int process_vsock_mux(const char *path, const char *port) {
×
95
        int r;
×
96

UNCOV
97
        assert(path);
×
98
        assert(port);
×
99

100
        /* We assume the path is absolute unless it starts with a dot (or is already explicitly absolute) */
UNCOV
101
        _cleanup_free_ char *prefixed = NULL;
×
102
        if (!STARTSWITH_SET(path, "/", "./")) {
×
103
                prefixed = strjoin("/", path);
×
104
                if (!prefixed)
×
105
                        return log_oom();
×
106

107
                path = prefixed;
108
        }
109

UNCOV
110
        _cleanup_close_ int fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
×
111
        if (fd < 0)
×
112
                return log_error_errno(errno, "Failed to allocate AF_UNIX socket: %m");
×
113

UNCOV
114
        r = connect_unix_path(fd, AT_FDCWD, path);
×
115
        if (r < 0)
×
116
                return log_error_errno(r, "Failed to connect to AF_UNIX socket %s: %m", path);
×
117

118
        /* Based on the protocol as defined here:
119
         * https://github.com/cloud-hypervisor/cloud-hypervisor/blob/main/docs/vsock.md
120
         * https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md */
UNCOV
121
        _cleanup_free_ char *connect_cmd = NULL;
×
122
        connect_cmd = strjoin("CONNECT ", port, "\n");
×
123
        if (!connect_cmd)
×
124
                return log_oom();
×
125

UNCOV
126
        r = loop_write(fd, connect_cmd, SIZE_MAX);
×
127
        if (r < 0)
×
128
                return log_error_errno(r, "Failed to send CONNECT to %s:%s: %m", path, port);
×
129

UNCOV
130
        r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* iovlen= */ 1, /* flags= */ 0);
×
131
        if (r < 0)
×
132
                return log_error_errno(r, "Failed to send socket via STDOUT: %m");
×
133

UNCOV
134
        log_debug("Successfully sent AF_UNIX socket via STDOUT.");
×
135
        return 0;
136
}
137

UNCOV
138
static int process_machine(const char *machine, const char *port) {
×
139
        _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
×
140
        int r;
×
141

UNCOV
142
        assert(machine);
×
143
        assert(port);
×
144

UNCOV
145
        r = sd_varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine");
×
146
        if (r < 0)
×
147
                return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m");
×
148

UNCOV
149
        _cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
×
150
        r = varlink_callbo_and_log(
×
151
                        vl,
152
                        "io.systemd.Machine.List",
153
                        &result,
154
                        SD_JSON_BUILD_PAIR("name", SD_JSON_BUILD_STRING(machine)));
UNCOV
155
        if (r < 0)
×
156
                return r;
157

UNCOV
158
        uint32_t cid = VMADDR_CID_ANY;
×
159

UNCOV
160
        static const sd_json_dispatch_field dispatch_table[] = {
×
161
                { "vSockCid", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, 0, 0 },
162
                {}
163
        };
164

UNCOV
165
        r = sd_json_dispatch(result, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &cid);
×
166
        if (r < 0)
×
167
                return log_error_errno(r, "Failed to parse Varlink reply: %m");
×
168

UNCOV
169
        if (cid == VMADDR_CID_ANY)
×
170
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Machine has no AF_VSOCK CID assigned.");
×
171

UNCOV
172
        return process_vsock_cid(cid, port);
×
173
}
174

175
static char *startswith_sep(const char *s, const char *prefix) {
6✔
176
        const char *p = startswith(s, prefix);
6✔
177

178
        if (p && IN_SET(*p, '/', '%'))
6✔
179
                return (char*) p + 1;
3✔
180

181
        return NULL;
182
}
183

184
static int run(int argc, char* argv[]) {
3✔
185

186
        log_setup();
3✔
187

188
        if (argc != 3)
3✔
UNCOV
189
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected two arguments: host and port.");
×
190

191
        const char *host = argv[1], *port = argv[2];
3✔
192

193
        const char *p = startswith_sep(host, "vsock");
3✔
194
        if (p)
3✔
UNCOV
195
                return process_vsock_string(p, port);
×
196

197
        p = startswith_sep(host, "unix");
3✔
198
        if (p)
3✔
199
                return process_unix(p);
3✔
200

UNCOV
201
        p = startswith_sep(host, "vsock-mux");
×
202
        if (p)
×
203
                return process_vsock_mux(p, port);
×
204

UNCOV
205
        p = startswith_sep(host, "machine");
×
206
        if (p)
×
207
                return process_machine(p, port);
×
208

UNCOV
209
        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Don't know how to parse host name specification: %s", host);
×
210
}
211

212
DEFINE_MAIN_FUNCTION(run);
3✔
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