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

systemd / systemd / 26669254190

29 May 2026 04:21PM UTC coverage: 72.986% (+0.01%) from 72.973%
26669254190

push

github

bluca
hwdb: reject overlong fnmatch key instead of passing NULL to fnmatch()

When the accumulated trie key exceeds the fixed-size line buffer,
linebuf_get() returns NULL. trie_fnmatch_f() passed that NULL straight
into fnmatch() as the pattern, causing a SIGSEGV on a crafted hwdb.bin
(reachable now that recursion is capped rather than overflowing the
stack first). Treat the NULL like the other corruption checks and
return -EBADMSG.

Follow-up for 73fea38cf

Fixes https://github.com/systemd/systemd/issues/42376

Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>

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

428 existing lines in 41 files now uncovered.

337411 of 462296 relevant lines covered (72.99%)

1276482.16 hits per line

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

68.66
/src/shared/module-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <syslog.h>
4

5
#include "sd-dlopen.h"
6

7
#include "log.h"
8
#include "module-util.h"
9
#include "proc-cmdline.h"
10
#include "strv.h"
11

12
#if HAVE_KMOD
13

14
DLSYM_PROTOTYPE(kmod_list_next) = NULL;
15
DLSYM_PROTOTYPE(kmod_load_resources) = NULL;
16
DLSYM_PROTOTYPE(kmod_module_get_initstate) = NULL;
17
DLSYM_PROTOTYPE(kmod_module_get_module) = NULL;
18
DLSYM_PROTOTYPE(kmod_module_get_name) = NULL;
19
DLSYM_PROTOTYPE(kmod_module_new_from_lookup) = NULL;
20
DLSYM_PROTOTYPE(kmod_module_probe_insert_module) = NULL;
21
DLSYM_PROTOTYPE(kmod_module_unref) = NULL;
22
DLSYM_PROTOTYPE(kmod_module_unref_list) = NULL;
23
DLSYM_PROTOTYPE(kmod_new) = NULL;
24
DLSYM_PROTOTYPE(kmod_set_log_fn) = NULL;
25
DLSYM_PROTOTYPE(kmod_unref) = NULL;
26
DLSYM_PROTOTYPE(kmod_validate_resources) = NULL;
27

28
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
×
29
        char ***denylist = ASSERT_PTR(data);
×
30
        int r;
×
31

32
        if (proc_cmdline_key_streq(key, "module_blacklist")) {
×
33

34
                if (proc_cmdline_value_missing(key, value))
×
35
                        return 0;
36

37
                r = strv_split_and_extend(denylist, value, ",", /* filter_duplicates= */ true);
×
38
                if (r < 0)
×
39
                        return r;
×
40
        }
41

42
        return 0;
43
}
44

45
int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) {
3,572✔
46
        _cleanup_(kmod_module_unref_listp) struct kmod_list *modlist = NULL;
3,572✔
47
        _cleanup_strv_free_ char **denylist = NULL;
3,572✔
48
        bool denylist_parsed = false;
3,572✔
49
        struct kmod_list *itr;
3,572✔
50
        int r;
3,572✔
51

52
        assert(ctx);
3,572✔
53
        assert(module);
3,572✔
54

55
        /* verbose==true means we should log at non-debug level if we
56
         * fail to find or load the module. */
57

58
        log_debug("Loading module: %s", module);
3,572✔
59

60
        r = sym_kmod_module_new_from_lookup(ctx, module, &modlist);
3,572✔
61
        if (r < 0)
3,572✔
62
                return log_full_errno(verbose ? LOG_ERR : LOG_DEBUG, r,
×
63
                                      "Failed to look up module alias '%s': %m", module);
64

65
        if (!modlist)
3,572✔
66
                return log_full_errno(verbose ? LOG_ERR : LOG_DEBUG,
1,387✔
67
                                      SYNTHETIC_ERRNO(ENOENT),
68
                                      "Failed to find module '%s'", module);
69

70
        sym_kmod_list_foreach(itr, modlist) {
5,134✔
71
                _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
2,949✔
72
                int state, err;
2,949✔
73

74
                mod = sym_kmod_module_get_module(itr);
2,949✔
75
                state = sym_kmod_module_get_initstate(mod);
2,949✔
76

77
                switch (state) {
2,949✔
78
                case KMOD_MODULE_BUILTIN:
79
                        log_full(verbose ? LOG_INFO : LOG_DEBUG,
1,385✔
80
                                 "Module '%s' is built in", sym_kmod_module_get_name(mod));
81
                        break;
82

83
                case KMOD_MODULE_LIVE:
84
                        log_debug("Module '%s' is already loaded", sym_kmod_module_get_name(mod));
522✔
85
                        break;
86

87
                default:
1,042✔
88
                        err = sym_kmod_module_probe_insert_module(
1,042✔
89
                                        mod,
90
                                        KMOD_PROBE_APPLY_BLACKLIST,
91
                                        /* extra_options= */ NULL,
92
                                        /* run_install= */ NULL,
93
                                        /* data= */ NULL,
94
                                        /* print_action= */ NULL);
95
                        if (err == 0)
1,042✔
96
                                log_full(verbose ? LOG_INFO : LOG_DEBUG,
885✔
97
                                         "Inserted module '%s'", sym_kmod_module_get_name(mod));
98
                        else if (err == KMOD_PROBE_APPLY_BLACKLIST)
157✔
99
                                log_full(verbose ? LOG_INFO : LOG_DEBUG,
×
100
                                         "Module '%s' is deny-listed (by kmod)", sym_kmod_module_get_name(mod));
101
                        else {
102
                                assert(err < 0);
157✔
103

104
                                if (err == -EPERM) {
157✔
105
                                        if (!denylist_parsed) {
×
106
                                                r = proc_cmdline_parse(parse_proc_cmdline_item, &denylist, 0);
×
107
                                                if (r < 0)
×
108
                                                        log_full_errno(!verbose ? LOG_DEBUG : LOG_WARNING,
×
109
                                                                       r,
110
                                                                       "Failed to parse kernel command line, ignoring: %m");
111

112
                                                denylist_parsed = true;
113
                                        }
114
                                        if (strv_contains(denylist, sym_kmod_module_get_name(mod))) {
×
115
                                                log_full(verbose ? LOG_INFO : LOG_DEBUG,
×
116
                                                         "Module '%s' is deny-listed (by kernel)", sym_kmod_module_get_name(mod));
117
                                                continue;
×
118
                                        }
119
                                }
120

121
                                log_full_errno(!verbose ? LOG_DEBUG :
157✔
122
                                               err == -ENODEV ? LOG_NOTICE :
123
                                               err == -ENOENT ? LOG_WARNING :
124
                                                                LOG_ERR,
125
                                               err,
126
                                               "Failed to insert module '%s': %m",
127
                                               sym_kmod_module_get_name(mod));
128
                                if (!IN_SET(err, -ENODEV, -ENOENT))
157✔
UNCOV
129
                                        r = err;
×
130
                        }
131
                }
132
        }
133

134
        return r;
135
}
136

137
_printf_(6,0) static void systemd_kmod_log(
×
138
                void *data,
139
                int priority,
140
                const char *file,
141
                int line,
142
                const char *fn,
143
                const char *format,
144
                va_list args) {
145

146
        log_internalv(priority, 0, file, line, fn, format, args);
×
147
}
×
148

149
int module_setup_context(struct kmod_ctx **ret) {
212✔
150
        _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
212✔
151
        int r;
212✔
152

153
        assert(ret);
212✔
154

155
        r = dlopen_libkmod(LOG_DEBUG);
212✔
156
        if (r < 0)
212✔
157
                return r;
158

159
        ctx = sym_kmod_new(NULL, NULL);
212✔
160
        if (!ctx)
212✔
161
                return -ENOMEM;
162

163
        (void) sym_kmod_load_resources(ctx);
212✔
164
        sym_kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
212✔
165

166
        *ret = TAKE_PTR(ctx);
212✔
167
        return 0;
212✔
168
}
169

170
#endif
171

172
int dlopen_libkmod(int log_level) {
269✔
173
#if HAVE_KMOD
174
        static void *libkmod_dl = NULL;
269✔
175

176
        SD_ELF_NOTE_DLOPEN(
269✔
177
                        "kmod",
178
                        "Support for loading kernel modules",
179
                        SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
180
                        "libkmod.so.2");
181

182
        return dlopen_many_sym_or_warn(
269✔
183
                        &libkmod_dl,
184
                        "libkmod.so.2",
185
                        log_level,
186
                        DLSYM_ARG(kmod_list_next),
187
                        DLSYM_ARG(kmod_load_resources),
188
                        DLSYM_ARG(kmod_module_get_initstate),
189
                        DLSYM_ARG(kmod_module_get_module),
190
                        DLSYM_ARG(kmod_module_get_name),
191
                        DLSYM_ARG(kmod_module_new_from_lookup),
192
                        DLSYM_ARG(kmod_module_probe_insert_module),
193
                        DLSYM_ARG(kmod_module_unref),
194
                        DLSYM_ARG(kmod_module_unref_list),
195
                        DLSYM_ARG(kmod_new),
196
                        DLSYM_ARG(kmod_set_log_fn),
197
                        DLSYM_ARG(kmod_unref),
198
                        DLSYM_ARG(kmod_validate_resources));
199
#else
200
        return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
201
                              "libkmod support is not compiled in.");
202
#endif
203
}
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