File: | build-scan/../src/binfmt/binfmt.c |
Warning: | line 39, column 12 Potential leak of memory pointed to by 'x' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <errno(*__errno_location ()).h> | |||
4 | #include <getopt.h> | |||
5 | #include <limits.h> | |||
6 | #include <stdbool.h> | |||
7 | #include <stdio.h> | |||
8 | #include <stdlib.h> | |||
9 | #include <string.h> | |||
10 | ||||
11 | #include "alloc-util.h" | |||
12 | #include "conf-files.h" | |||
13 | #include "def.h" | |||
14 | #include "fd-util.h" | |||
15 | #include "fileio.h" | |||
16 | #include "log.h" | |||
17 | #include "pager.h" | |||
18 | #include "string-util.h" | |||
19 | #include "strv.h" | |||
20 | #include "terminal-util.h" | |||
21 | #include "util.h" | |||
22 | ||||
23 | static bool_Bool arg_cat_config = false0; | |||
24 | static bool_Bool arg_no_pager = false0; | |||
25 | ||||
26 | static int delete_rule(const char *rule) { | |||
27 | _cleanup_free___attribute__((cleanup(freep))) char *x = NULL((void*)0), *fn = NULL((void*)0); | |||
28 | char *e; | |||
29 | ||||
30 | assert(rule[0])do { if ((__builtin_expect(!!(!(rule[0])),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rule[0]"), "../src/binfmt/binfmt.c", 30 , __PRETTY_FUNCTION__); } while (0); | |||
31 | ||||
32 | x = strdup(rule); | |||
33 | if (!x) | |||
34 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/binfmt/binfmt.c", 34, __func__); | |||
35 | ||||
36 | e = strchrnul(x+1, x[0]); | |||
37 | *e = 0; | |||
38 | ||||
39 | fn = strappend("/proc/sys/fs/binfmt_misc/", x+1); | |||
| ||||
40 | if (!fn) | |||
41 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/binfmt/binfmt.c", 41, __func__); | |||
42 | ||||
43 | return write_string_file(fn, "-1", 0); | |||
44 | } | |||
45 | ||||
46 | static int apply_rule(const char *rule) { | |||
47 | int r; | |||
48 | ||||
49 | delete_rule(rule); | |||
50 | ||||
51 | r = write_string_file("/proc/sys/fs/binfmt_misc/register", rule, 0); | |||
52 | if (r < 0) | |||
53 | return log_error_errno(r, "Failed to add binary format: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/binfmt/binfmt.c", 53, __func__, "Failed to add binary format: %m" ) : -abs(_e); }); | |||
54 | ||||
55 | return 0; | |||
56 | } | |||
57 | ||||
58 | static int apply_file(const char *path, bool_Bool ignore_enoent) { | |||
59 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
60 | int r; | |||
61 | ||||
62 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/binfmt/binfmt.c", 62, __PRETTY_FUNCTION__ ); } while (0); | |||
63 | ||||
64 | r = search_and_fopen(path, "re", NULL((void*)0), (const char**) CONF_PATHS_STRV("binfmt.d")((char**) ((const char*[]) { "/etc/" "binfmt.d", "/run/" "binfmt.d" , "/usr/local/lib/" "binfmt.d", "/usr/lib/" "binfmt.d", ((void *)0) })), &f); | |||
65 | if (r < 0) { | |||
66 | if (ignore_enoent && r == -ENOENT2) | |||
67 | return 0; | |||
68 | ||||
69 | return log_error_errno(r, "Failed to open file '%s', ignoring: %m", path)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/binfmt/binfmt.c", 69, __func__, "Failed to open file '%s', ignoring: %m" , path) : -abs(_e); }); | |||
70 | } | |||
71 | ||||
72 | log_debug("apply: %s", path)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/binfmt/binfmt.c", 72, __func__, "apply: %s", path) : -abs(_e); }); | |||
73 | for (;;) { | |||
74 | char l[LINE_MAX2048], *p; | |||
75 | int k; | |||
76 | ||||
77 | if (!fgets(l, sizeof(l), f)) { | |||
78 | if (feof(f)) | |||
79 | break; | |||
80 | ||||
81 | return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/binfmt/binfmt.c", 81, __func__, "Failed to read file '%s', ignoring: %m" , path) : -abs(_e); }); | |||
82 | } | |||
83 | ||||
84 | p = strstrip(l); | |||
85 | if (!*p) | |||
86 | continue; | |||
87 | if (strchr(COMMENTS"#;" "\n", *p)) | |||
88 | continue; | |||
89 | ||||
90 | k = apply_rule(p); | |||
91 | if (k < 0 && r == 0) | |||
92 | r = k; | |||
93 | } | |||
94 | ||||
95 | return r; | |||
96 | } | |||
97 | ||||
98 | static void help(void) { | |||
99 | printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" | |||
100 | "Registers binary formats.\n\n" | |||
101 | " -h --help Show this help\n" | |||
102 | " --version Show package version\n" | |||
103 | " --cat-config Show configuration files\n" | |||
104 | " --no-pager Do not pipe output into a pager\n" | |||
105 | , program_invocation_short_name); | |||
106 | } | |||
107 | ||||
108 | static int parse_argv(int argc, char *argv[]) { | |||
109 | ||||
110 | enum { | |||
111 | ARG_VERSION = 0x100, | |||
112 | ARG_CAT_CONFIG, | |||
113 | ARG_NO_PAGER, | |||
114 | }; | |||
115 | ||||
116 | static const struct option options[] = { | |||
117 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
118 | { "version", no_argument0, NULL((void*)0), ARG_VERSION }, | |||
119 | { "cat-config", no_argument0, NULL((void*)0), ARG_CAT_CONFIG }, | |||
120 | { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER }, | |||
121 | {} | |||
122 | }; | |||
123 | ||||
124 | int c; | |||
125 | ||||
126 | assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/binfmt/binfmt.c" , 126, __PRETTY_FUNCTION__); } while (0); | |||
127 | assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argv"), "../src/binfmt/binfmt.c", 127, __PRETTY_FUNCTION__ ); } while (0); | |||
128 | ||||
129 | while ((c = getopt_long(argc, argv, "h", options, NULL((void*)0))) >= 0) | |||
130 | ||||
131 | switch (c) { | |||
132 | ||||
133 | case 'h': | |||
134 | help(); | |||
135 | return 0; | |||
136 | ||||
137 | case ARG_VERSION: | |||
138 | return version(); | |||
139 | ||||
140 | case ARG_CAT_CONFIG: | |||
141 | arg_cat_config = true1; | |||
142 | break; | |||
143 | ||||
144 | case ARG_NO_PAGER: | |||
145 | arg_no_pager = true1; | |||
146 | break; | |||
147 | ||||
148 | case '?': | |||
149 | return -EINVAL22; | |||
150 | ||||
151 | default: | |||
152 | assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unhandled option"), "../src/binfmt/binfmt.c", 152, __PRETTY_FUNCTION__ ); } while (0); | |||
153 | } | |||
154 | ||||
155 | if (arg_cat_config && argc > optind) { | |||
156 | log_error("Positional arguments are not allowed with --cat-config")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/binfmt/binfmt.c", 156, __func__, "Positional arguments are not allowed with --cat-config" ) : -abs(_e); }); | |||
157 | return -EINVAL22; | |||
158 | } | |||
159 | ||||
160 | return 1; | |||
161 | } | |||
162 | ||||
163 | int main(int argc, char *argv[]) { | |||
164 | int r, k; | |||
165 | ||||
166 | r = parse_argv(argc, argv); | |||
167 | if (r <= 0) | |||
| ||||
168 | return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0; | |||
169 | ||||
170 | log_set_target(LOG_TARGET_AUTO); | |||
171 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
172 | log_open(); | |||
173 | ||||
174 | umask(0022); | |||
175 | ||||
176 | r = 0; | |||
177 | ||||
178 | if (argc > optind) { | |||
179 | int i; | |||
180 | ||||
181 | for (i = optind; i < argc; i++) { | |||
182 | k = apply_file(argv[i], false0); | |||
183 | if (k < 0 && r == 0) | |||
184 | r = k; | |||
185 | } | |||
186 | } else { | |||
187 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **files = NULL((void*)0); | |||
188 | char **f; | |||
189 | ||||
190 | r = conf_files_list_strv(&files, ".conf", NULL((void*)0), 0, (const char**) CONF_PATHS_STRV("binfmt.d")((char**) ((const char*[]) { "/etc/" "binfmt.d", "/run/" "binfmt.d" , "/usr/local/lib/" "binfmt.d", "/usr/lib/" "binfmt.d", ((void *)0) }))); | |||
191 | if (r < 0) { | |||
192 | log_error_errno(r, "Failed to enumerate binfmt.d files: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/binfmt/binfmt.c", 192, __func__, "Failed to enumerate binfmt.d files: %m" ) : -abs(_e); }); | |||
193 | goto finish; | |||
194 | } | |||
195 | ||||
196 | if (arg_cat_config
| |||
197 | (void) pager_open(arg_no_pager, false0); | |||
198 | ||||
199 | r = cat_files(NULL((void*)0), files, 0); | |||
200 | goto finish; | |||
201 | } | |||
202 | ||||
203 | /* Flush out all rules */ | |||
204 | write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", 0); | |||
205 | ||||
206 | STRV_FOREACH(f, files)for ((f) = (files); (f) && *(f); (f)++) { | |||
207 | k = apply_file(*f, true1); | |||
208 | if (k < 0 && r == 0) | |||
209 | r = k; | |||
210 | } | |||
211 | } | |||
212 | ||||
213 | finish: | |||
214 | pager_close(); | |||
215 | ||||
216 | return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0; | |||
217 | } |