| 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 | } |