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

systemd / systemd / 23367620641

20 Mar 2026 07:25PM UTC coverage: 72.606% (+0.3%) from 72.351%
23367620641

push

github

bluca
kmod-setup: load vsock_loopback alongside vsock

Loading vmw_vsock_virtio_transport early at boot causes vsock to be
resident before any application opens an AF_VSOCK socket. Because the
kernel skips autoloading when the vsock module is already present,
vsock_loopback never gets loaded automatically, and any subsequent
bind() to VMADDR_CID_LOCAL fails with EADDRNOTAVAIL.

Fix this by explicitly loading vsock_loopback on virtio or VMWare
machines via the new may_have_vsock_looopback() helper, wich covers both
vmw_vsock_virtio_transport and vmware_vsock_vmci_transport case.
vsock_loopback is the only module that registers a transport for
VMADDR_CID_LOCAL (CID 1) and has no hard dependency from any of the
vsock transport modules.

Fixes: #41100
Follow-up for 381c78db4

2 of 2 new or added lines in 1 file covered. (100.0%)

2634 existing lines in 55 files now uncovered.

316477 of 435881 relevant lines covered (72.61%)

1159615.85 hits per line

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

0.0
/src/shared/kernel-image.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "alloc-util.h"
4
#include "env-file.h"
5
#include "fd-util.h"
6
#include "fs-util.h"
7
#include "kernel-image.h"
8
#include "log.h"
9
#include "pe-binary.h"
10
#include "string-table.h"
11
#include "string-util.h"
12

13
#define PE_SECTION_READ_MAX (16U*1024U)
14

15
static const char * const kernel_image_type_table[_KERNEL_IMAGE_TYPE_MAX] = {
16
        [KERNEL_IMAGE_TYPE_UNKNOWN] = "unknown",
17
        [KERNEL_IMAGE_TYPE_UKI]     = "uki",
18
        [KERNEL_IMAGE_TYPE_ADDON]   = "addon",
19
        [KERNEL_IMAGE_TYPE_PE]      = "pe",
20
};
21

22
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(kernel_image_type, KernelImageType);
×
23

24
static int uki_read_pretty_name(
×
25
                int fd,
26
                const PeHeader *pe_header,
27
                const IMAGE_SECTION_HEADER *sections,
28
                char **ret) {
29

30
        _cleanup_free_ char *pname = NULL, *name = NULL;
×
31
        _cleanup_free_ void *osrel = NULL;
×
32
        size_t osrel_size;
×
33
        int r;
×
34

UNCOV
35
        assert(fd >= 0);
×
36
        assert(pe_header);
×
37
        assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0);
×
38
        assert(ret);
×
39

UNCOV
40
        r = pe_read_section_data_by_name(
×
41
                        fd,
42
                        pe_header,
43
                        sections,
44
                        ".osrel",
45
                        /* max_size= */ PE_SECTION_READ_MAX,
46
                        &osrel,
47
                        &osrel_size);
UNCOV
48
        if (r == -ENXIO) { /* Section not found */
×
49
                *ret = NULL;
×
50
                return 0;
×
51
        }
52

UNCOV
53
        r = parse_env_data(
×
54
                        osrel, osrel_size, ".osrel",
55
                        "PRETTY_NAME", &pname,
56
                        "NAME",        &name);
UNCOV
57
        if (r < 0)
×
58
                return log_error_errno(r, "Failed to parse embedded os-release file: %m");
×
59

60
        /* follow the same logic as os_release_pretty_name() */
UNCOV
61
        if (!isempty(pname))
×
62
                *ret = TAKE_PTR(pname);
×
63
        else if (!isempty(name))
×
UNCOV
64
                *ret = TAKE_PTR(name);
×
65
        else {
66
                char *n = strdup("Linux");
×
67
                if (!n)
×
68
                        return log_oom();
×
69

UNCOV
70
                *ret = n;
×
71
        }
72

73
        return 0;
74
}
75

UNCOV
76
static int inspect_uki(
×
77
                int fd,
78
                const PeHeader *pe_header,
79
                const IMAGE_SECTION_HEADER *sections,
80
                char **ret_cmdline,
81
                char **ret_uname,
82
                char **ret_pretty_name) {
83

UNCOV
84
        _cleanup_free_ char *cmdline = NULL, *uname = NULL, *pname = NULL;
×
UNCOV
85
        int r;
×
86

UNCOV
87
        assert(fd >= 0);
×
UNCOV
88
        assert(sections || le16toh(pe_header->pe.NumberOfSections) == 0);
×
89

90
        if (ret_cmdline) {
×
UNCOV
91
                r = pe_read_section_data_by_name(fd, pe_header, sections, ".cmdline", PE_SECTION_READ_MAX, (void**) &cmdline, NULL);
×
92
                if (r < 0 && r != -ENXIO) /* If the section doesn't exist, that's fine */
×
93
                        return r;
94
        }
95

96
        if (ret_uname) {
×
97
                r = pe_read_section_data_by_name(fd, pe_header, sections, ".uname", PE_SECTION_READ_MAX, (void**) &uname, NULL);
×
UNCOV
98
                if (r < 0 && r != -ENXIO) /* If the section doesn't exist, that's fine */
×
99
                        return r;
100
        }
101

102
        if (ret_pretty_name) {
×
103
                r = uki_read_pretty_name(fd, pe_header, sections, &pname);
×
UNCOV
104
                if (r < 0)
×
105
                        return r;
106
        }
107

108
        if (ret_cmdline)
×
109
                *ret_cmdline = TAKE_PTR(cmdline);
×
UNCOV
110
        if (ret_uname)
×
UNCOV
111
                *ret_uname = TAKE_PTR(uname);
×
UNCOV
112
        if (ret_pretty_name)
×
113
                *ret_pretty_name = TAKE_PTR(pname);
×
114

115
        return 0;
116
}
117

118
int inspect_kernel(
×
119
                int dir_fd,
120
                const char *filename,
121
                KernelImageType *ret_type,
122
                char **ret_cmdline,
123
                char **ret_uname,
124
                char **ret_pretty_name) {
125

UNCOV
126
        _cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
×
UNCOV
127
        _cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
×
UNCOV
128
        KernelImageType t = KERNEL_IMAGE_TYPE_UNKNOWN;
×
UNCOV
129
        _cleanup_free_ PeHeader *pe_header = NULL;
×
UNCOV
130
        _cleanup_close_ int fd = -EBADF;
×
131
        int r;
×
132

133
        assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
×
134
        assert(filename);
×
135

136
        fd = xopenat(dir_fd, filename, O_RDONLY|O_CLOEXEC);
×
UNCOV
137
        if (fd < 0)
×
138
                return log_error_errno(fd, "Failed to open kernel image file '%s': %m", filename);
×
139

UNCOV
140
        r = pe_load_headers(fd, &dos_header, &pe_header);
×
141
        if (r == -EBADMSG) /* not a valid PE file */
×
142
                goto not_uki;
×
143
        if (r < 0)
×
UNCOV
144
                return log_error_errno(r, "Failed to parse kernel image file '%s': %m", filename);
×
145

146
        r = pe_load_sections(fd, dos_header, pe_header, &sections);
×
147
        if (r == -EBADMSG) /* not a valid PE file */
×
148
                goto not_uki;
×
149
        if (r < 0)
×
UNCOV
150
                return log_error_errno(r, "Failed to load PE sections from kernel image file '%s': %m", filename);
×
151

152
        if (pe_is_uki(pe_header, sections)) {
×
153
                r = inspect_uki(fd, pe_header, sections, ret_cmdline, ret_uname, ret_pretty_name);
×
154
                if (r < 0)
×
155
                        return r;
156

157
                t = KERNEL_IMAGE_TYPE_UKI;
×
158
                goto done;
×
159
        } else if (pe_is_addon(pe_header, sections)) {
×
UNCOV
160
                r = inspect_uki(fd, pe_header, sections, ret_cmdline, ret_uname, /* ret_pretty_name= */ NULL);
×
UNCOV
161
                if (r < 0)
×
162
                        return r;
163

164
                if (ret_pretty_name)
×
165
                        *ret_pretty_name = NULL;
×
166

UNCOV
167
                t = KERNEL_IMAGE_TYPE_ADDON;
×
UNCOV
168
                goto done;
×
169
        } else
170
                t = KERNEL_IMAGE_TYPE_PE;
171

172
not_uki:
×
173
        if (ret_cmdline)
×
UNCOV
174
                *ret_cmdline = NULL;
×
UNCOV
175
        if (ret_uname)
×
UNCOV
176
                *ret_uname = NULL;
×
177
        if (ret_pretty_name)
×
178
                *ret_pretty_name = NULL;
×
179

180
done:
×
181
        if (ret_type)
×
182
                *ret_type = t;
×
183

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

© 2026 Coveralls, Inc