tree-wide: several cleanups and fixlets prompted by Coverity (#36431)

This commit is contained in:
Lennart Poettering
2025-03-03 23:17:28 +01:00
committed by GitHub
7 changed files with 117 additions and 122 deletions

View File

@@ -244,17 +244,13 @@ static int write_string_file_atomic_at(
}
r = fopen_temporary_at(dir_fd, fn, &f, &p);
if (call_label_ops_post)
/* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures
* in label_ops_post(). */
RET_GATHER(r, label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f));
if (r < 0)
goto fail;
if (call_label_ops_post) {
call_label_ops_post = false;
r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true);
if (r < 0)
goto fail;
}
r = write_string_stream_full(f, line, flags, ts);
if (r < 0)
goto fail;
@@ -277,9 +273,6 @@ static int write_string_file_atomic_at(
return 0;
fail:
if (call_label_ops_post)
(void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f);
if (f)
(void) unlinkat(dir_fd, p, 0);
return r;
@@ -293,7 +286,7 @@ int write_string_file_full(
const struct timespec *ts,
const char *label_fn) {
bool call_label_ops_post = false, made_file = false;
bool made_file = false;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -EBADF;
int r;
@@ -325,11 +318,13 @@ int write_string_file_full(
/* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
if (isempty(fn))
fd = fd_reopen(ASSERT_FD(dir_fd), O_CLOEXEC | O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY));
r = fd = fd_reopen(
ASSERT_FD(dir_fd), O_CLOEXEC | O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY));
else {
mode_t mode = write_string_file_flags_to_mode(flags);
bool call_label_ops_post = false;
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
r = label_ops_pre(dir_fd, label_fn ?: fn, mode);
@@ -339,7 +334,7 @@ int write_string_file_full(
call_label_ops_post = true;
}
fd = openat_report_new(
r = fd = openat_report_new(
dir_fd, fn, O_CLOEXEC | O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
@@ -347,19 +342,13 @@ int write_string_file_full(
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
mode,
&made_file);
if (call_label_ops_post)
/* If openat_report_new() failed in the above, propagate the error code, and ignore
* failures in label_ops_post(). */
RET_GATHER(r, label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file));
}
if (fd < 0) {
r = fd;
if (r < 0)
goto fail;
}
if (call_label_ops_post) {
call_label_ops_post = false;
r = label_ops_post(fd, /* path= */ NULL, made_file);
if (r < 0)
goto fail;
}
r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0)
@@ -375,9 +364,6 @@ int write_string_file_full(
return 0;
fail:
if (call_label_ops_post)
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file);
if (made_file)
(void) unlinkat(dir_fd, fn, 0);

View File

@@ -646,6 +646,7 @@ static int setup_confirm_stdio(
_cleanup_close_ int fd = -EBADF, saved_stdin = -EBADF, saved_stdout = -EBADF;
int r;
assert(context);
assert(ret_saved_stdin);
assert(ret_saved_stdout);
@@ -883,16 +884,16 @@ static int get_fixed_group(
return 0;
}
static int get_supplementary_groups(const ExecContext *c, const char *user,
const char *group, gid_t gid,
gid_t **supplementary_gids, int *ngids) {
int r, k = 0;
int ngroups_max;
bool keep_groups = false;
gid_t *groups = NULL;
_cleanup_free_ gid_t *l_gids = NULL;
static int get_supplementary_groups(
const ExecContext *c,
const char *user,
gid_t gid,
gid_t **ret_gids) {
int r;
assert(c);
assert(ret_gids);
/*
* If user is given, then lookup GID and supplementary groups list.
@@ -900,6 +901,7 @@ static int get_supplementary_groups(const ExecContext *c, const char *user,
* here and as early as possible so we keep the list of supplementary
* groups of the caller.
*/
bool keep_groups = false;
if (user && gid_is_valid(gid) && gid != 0) {
/* First step, initialize groups from /etc/groups */
if (initgroups(user, gid) < 0)
@@ -908,22 +910,25 @@ static int get_supplementary_groups(const ExecContext *c, const char *user,
keep_groups = true;
}
if (strv_isempty(c->supplementary_groups))
if (strv_isempty(c->supplementary_groups)) {
*ret_gids = NULL;
return 0;
}
/*
* If SupplementaryGroups= was passed then NGROUPS_MAX has to
* be positive, otherwise fail.
*/
errno = 0;
ngroups_max = (int) sysconf(_SC_NGROUPS_MAX);
int ngroups_max = (int) sysconf(_SC_NGROUPS_MAX);
if (ngroups_max <= 0)
return errno_or_else(EOPNOTSUPP);
l_gids = new(gid_t, ngroups_max);
_cleanup_free_ gid_t *l_gids = new(gid_t, ngroups_max);
if (!l_gids)
return -ENOMEM;
int k = 0;
if (keep_groups) {
/*
* Lookup the list of groups that the user belongs to, we
@@ -932,43 +937,32 @@ static int get_supplementary_groups(const ExecContext *c, const char *user,
k = ngroups_max;
if (getgrouplist(user, gid, l_gids, &k) < 0)
return -EINVAL;
} else
k = 0;
}
STRV_FOREACH(i, c->supplementary_groups) {
const char *g;
if (k >= ngroups_max)
return -E2BIG;
g = *i;
r = get_group_creds(&g, l_gids+k, 0);
const char *g = *i;
r = get_group_creds(&g, l_gids + k, /* flags = */ 0);
if (r < 0)
return r;
k++;
}
/*
* Sets ngids to zero to drop all supplementary groups, happens
* when we are under root and SupplementaryGroups= is empty.
*/
if (k == 0) {
*ngids = 0;
*ret_gids = NULL;
return 0;
}
/* Otherwise get the final list of supplementary groups */
groups = memdup(l_gids, sizeof(gid_t) * k);
gid_t *groups = newdup(gid_t, l_gids, k);
if (!groups)
return -ENOMEM;
*supplementary_gids = groups;
*ngids = k;
groups = NULL;
return 0;
*ret_gids = groups;
return k;
}
static int enforce_groups(gid_t gid, const gid_t *supplementary_gids, int ngids) {
@@ -1013,9 +1007,11 @@ static int enforce_user(
const ExecContext *context,
uid_t uid,
uint64_t capability_ambient_set) {
assert(context);
int r;
assert(context);
if (!uid_is_valid(uid))
return 0;
@@ -1441,6 +1437,8 @@ static bool context_has_syscall_logs(const ExecContext *c) {
}
static bool context_has_seccomp(const ExecContext *c) {
assert(c);
/* We need NNP if we have any form of seccomp and are unprivileged */
return c->lock_personality ||
c->memory_deny_write_execute ||
@@ -1502,7 +1500,10 @@ static bool seccomp_allows_drop_privileges(const ExecContext *c) {
return !(has_capget || has_capset || has_prctl);
}
static bool skip_seccomp_unavailable(const ExecContext *c, const ExecParameters *p, const char* msg) {
static bool skip_seccomp_unavailable(const ExecContext *c, const ExecParameters *p, const char *msg) {
assert(c);
assert(p);
assert(msg);
if (is_seccomp_available())
return false;
@@ -1801,6 +1802,7 @@ static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p,
assert(c);
assert(p);
assert(ret_exit_status);
if (c->protect_hostname == PROTECT_HOSTNAME_NO)
return 0;
@@ -1907,6 +1909,7 @@ static int build_environment(
assert(c);
assert(p);
assert(cgroup_context);
assert(ret);
#define N_ENV_VARS 20
@@ -2125,7 +2128,7 @@ static int build_environment(
our_env[n_env++] = x;
if (cgroup_context && !path_equal(memory_pressure_path, "/dev/null")) {
if (!path_equal(memory_pressure_path, "/dev/null")) {
_cleanup_free_ char *b = NULL, *e = NULL;
if (asprintf(&b, "%s " USEC_FMT " " USEC_FMT,
@@ -2166,6 +2169,9 @@ static int build_pass_environment(const ExecContext *c, char ***ret) {
_cleanup_strv_free_ char **pass_env = NULL;
size_t n_env = 0;
assert(c);
assert(ret);
STRV_FOREACH(i, c->pass_environment) {
_cleanup_free_ char *x = NULL;
char *v;
@@ -2185,7 +2191,6 @@ static int build_pass_environment(const ExecContext *c, char ***ret) {
}
*ret = TAKE_PTR(pass_env);
return 0;
}
@@ -2390,7 +2395,7 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
return 1;
}
static int can_mount_proc(const ExecContext *c, ExecParameters *p) {
static int can_mount_proc(const ExecContext *c, const ExecParameters *p) {
_cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
_cleanup_(sigkill_waitp) pid_t pid = 0;
ssize_t n;
@@ -2893,11 +2898,12 @@ fail:
#if ENABLE_SMACK
static int setup_smack(
const ExecParameters *params,
const ExecContext *context,
const ExecParameters *params,
int executable_fd) {
int r;
assert(context);
assert(params);
assert(executable_fd >= 0);
@@ -3165,13 +3171,14 @@ static int setup_ephemeral(
int r;
assert(context);
assert(runtime);
assert(root_image);
assert(root_directory);
if (!*root_image && !*root_directory)
return 0;
if (!runtime || !runtime->ephemeral_copy)
if (!runtime->ephemeral_copy)
return 0;
assert(runtime->ephemeral_storage_socket[0] >= 0);
@@ -3383,6 +3390,8 @@ static int apply_mount_namespace(
int r;
assert(context);
assert(params);
assert(runtime);
CLEANUP_ARRAY(bind_mounts, n_bind_mounts, bind_mount_free_many);
@@ -3430,7 +3439,7 @@ static int apply_mount_namespace(
* to world users. Inside of it there's a /tmp that is sticky, and that's the one we want to
* use here. This does not apply when we are using /run/systemd/empty as fallback. */
if (context->private_tmp == PRIVATE_TMP_CONNECTED && runtime && runtime->shared) {
if (context->private_tmp == PRIVATE_TMP_CONNECTED && runtime->shared) {
if (streq_ptr(runtime->shared->tmp_dir, RUN_SYSTEMD_EMPTY))
tmp_dir = runtime->shared->tmp_dir;
else if (runtime->shared->tmp_dir)
@@ -3622,6 +3631,8 @@ static int apply_working_directory(
int r;
assert(context);
assert(params);
assert(runtime);
if (context->working_directory_home) {
/* Preferably use the data from $HOME, in case it was updated by a PAM module */
@@ -3642,7 +3653,7 @@ static int apply_working_directory(
_cleanup_close_ int dfd = -EBADF;
r = chase(wd,
(runtime ? runtime->ephemeral_copy : NULL) ?: context->root_directory,
runtime->ephemeral_copy ?: context->root_directory,
CHASE_PREFIX_ROOT|CHASE_AT_RESOLVE_IN_ROOT,
/* ret_path= */ NULL,
&dfd);
@@ -3660,11 +3671,13 @@ static int apply_root_directory(
int *exit_status) {
assert(context);
assert(params);
assert(runtime);
assert(exit_status);
if (params->flags & EXEC_APPLY_CHROOT)
if (!needs_mount_ns && context->root_directory)
if (chroot((runtime ? runtime->ephemeral_copy : NULL) ?: context->root_directory) < 0) {
if (chroot(runtime->ephemeral_copy ?: context->root_directory) < 0) {
*exit_status = EXIT_CHROOT;
return -errno;
}
@@ -3675,7 +3688,8 @@ static int apply_root_directory(
static int setup_keyring(
const ExecContext *context,
const ExecParameters *p,
uid_t uid, gid_t gid) {
uid_t uid,
gid_t gid) {
key_serial_t keyring;
int r = 0;
@@ -3832,12 +3846,14 @@ static int close_remaining_fds(
const ExecParameters *params,
const ExecRuntime *runtime,
int socket_fd,
const int *fds, size_t n_fds) {
const int *fds,
size_t n_fds) {
size_t n_dont_close = 0;
int dont_close[n_fds + 17];
assert(params);
assert(runtime);
if (params->stdin_fd >= 0)
dont_close[n_dont_close++] = params->stdin_fd;
@@ -3853,15 +3869,14 @@ static int close_remaining_fds(
n_dont_close += n_fds;
}
if (runtime)
append_socket_pair(dont_close, &n_dont_close, runtime->ephemeral_storage_socket);
append_socket_pair(dont_close, &n_dont_close, runtime->ephemeral_storage_socket);
if (runtime && runtime->shared) {
if (runtime->shared) {
append_socket_pair(dont_close, &n_dont_close, runtime->shared->netns_storage_socket);
append_socket_pair(dont_close, &n_dont_close, runtime->shared->ipcns_storage_socket);
}
if (runtime && runtime->dynamic_creds) {
if (runtime->dynamic_creds) {
if (runtime->dynamic_creds->user)
append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->user->storage_socket);
if (runtime->dynamic_creds->group)
@@ -4279,11 +4294,12 @@ static int setup_delegated_namespaces(
assert(context);
assert(params);
assert(runtime);
assert(reterr_exit_status);
if (exec_needs_network_namespace(context) &&
exec_namespace_is_delegated(context, params, CLONE_NEWNET) == delegate &&
runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
/* Try to enable network namespacing if network namespacing is available and we have
* CAP_NET_ADMIN in the current user namespace (either the system manager one or the unit's
@@ -4310,7 +4326,7 @@ static int setup_delegated_namespaces(
if (exec_needs_ipc_namespace(context) &&
exec_namespace_is_delegated(context, params, CLONE_NEWIPC) == delegate &&
runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
if (ns_type_supported(NAMESPACE_IPC)) {
r = setup_shareable_ns(runtime->shared->ipcns_storage_socket, CLONE_NEWIPC);
@@ -4600,8 +4616,7 @@ int exec_invoke(
int *exit_status) {
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **joined_exec_search_path = NULL, **accum_env = NULL, **replaced_argv = NULL;
int r, ngids = 0;
_cleanup_free_ gid_t *supplementary_gids = NULL;
int r;
const char *username = NULL, *groupname = NULL;
_cleanup_free_ char *home_buffer = NULL, *memory_pressure_path = NULL, *own_user = NULL;
const char *pwent_home = NULL, *shell = NULL;
@@ -4633,15 +4648,16 @@ int exec_invoke(
size_t n_fds, /* fds to pass to the child */
n_keep_fds; /* total number of fds not to close */
int secure_bits;
_cleanup_free_ gid_t *gids_after_pam = NULL;
int ngids_after_pam = 0;
_cleanup_free_ gid_t *gids = NULL, *gids_after_pam = NULL;
int ngids = 0, ngids_after_pam = 0;
int socket_fd = -EBADF, named_iofds[3] = EBADF_TRIPLET;
size_t n_storage_fds, n_socket_fds, n_extra_fds;
assert(command);
assert(context);
assert(params);
assert(runtime);
assert(cgroup_context);
assert(exit_status);
/* This should be mostly redundant, as the log level is also passed as an argument of the executor,
@@ -4802,7 +4818,7 @@ int exec_invoke(
return log_exec_error_errno(context, params, errno, "Failed to update environment: %m");
}
if (context->dynamic_user && runtime && runtime->dynamic_creds) {
if (context->dynamic_user && runtime->dynamic_creds) {
_cleanup_strv_free_ char **suggested_paths = NULL;
/* On top of that, make sure we bypass our own NSS module nss-systemd comprehensively for any NSS
@@ -4874,11 +4890,10 @@ int exec_invoke(
}
/* Initialize user supplementary groups and get SupplementaryGroups= ones */
r = get_supplementary_groups(context, username, groupname, gid,
&supplementary_gids, &ngids);
if (r < 0) {
ngids = get_supplementary_groups(context, username, gid, &gids);
if (ngids < 0) {
*exit_status = EXIT_GROUP;
return log_exec_error_errno(context, params, r, "Failed to determine supplementary groups: %m");
return log_exec_error_errno(context, params, ngids, "Failed to determine supplementary groups: %m");
}
r = send_user_lookup(params->unit_id, params->user_lookup_fd, uid, gid);
@@ -4924,7 +4939,7 @@ int exec_invoke(
}
}
if (context->network_namespace_path && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
if (context->network_namespace_path && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
r = open_shareable_ns_path(runtime->shared->netns_storage_socket, context->network_namespace_path, CLONE_NEWNET);
if (r < 0) {
*exit_status = EXIT_NETWORK;
@@ -4932,7 +4947,7 @@ int exec_invoke(
}
}
if (context->ipc_namespace_path && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
if (context->ipc_namespace_path && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
r = open_shareable_ns_path(runtime->shared->ipcns_storage_socket, context->ipc_namespace_path, CLONE_NEWIPC);
if (r < 0) {
*exit_status = EXIT_NAMESPACE;
@@ -5153,7 +5168,7 @@ int exec_invoke(
}
}
if (cgroup_context && cg_unified() > 0 && is_pressure_supported() > 0) {
if (cg_unified() > 0 && is_pressure_supported() > 0) {
if (cgroup_context_want_memory_pressure(cgroup_context)) {
r = cg_get_path("memory", params->cgroup_path, "memory.pressure", &memory_pressure_path);
if (r < 0) {
@@ -5382,9 +5397,9 @@ int exec_invoke(
* For non-root in a userns, devices will be owned by the user/group before the group change, and nobody. */
if (needs_setuid) {
_cleanup_free_ gid_t *gids_to_enforce = NULL;
int ngids_to_enforce = 0;
int ngids_to_enforce;
ngids_to_enforce = merge_gid_lists(supplementary_gids,
ngids_to_enforce = merge_gid_lists(gids,
ngids,
gids_after_pam,
ngids_after_pam,
@@ -5536,7 +5551,7 @@ int exec_invoke(
/* LSM Smack needs the capability CAP_MAC_ADMIN to change the current execution security context of the
* process. This is the latest place before dropping capabilities. Other MAC context are set later. */
if (use_smack) {
r = setup_smack(params, context, executable_fd);
r = setup_smack(context, params, executable_fd);
if (r < 0 && !context->smack_process_label_ignore) {
*exit_status = EXIT_SMACK_PROCESS_LABEL;
return log_exec_error_errno(context, params, r, "Failed to set SMACK process label: %m");

View File

@@ -49,7 +49,7 @@ int asynchronous_fsync(int fd, pid_t *ret_pid) {
return r;
if (r == 0) {
/* Child process */
fsync(fd);
(void) fsync(fd);
_exit(EXIT_SUCCESS);
}

View File

@@ -1028,5 +1028,5 @@ bool generator_soft_rebooted(void) {
return (cached = false);
}
return (cached = u > 0);
return (cached = (u > 0));
}

View File

@@ -462,7 +462,7 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
_cleanup_fclose_ FILE *f = NULL;
_cleanup_strv_free_ char **match_list = NULL;
uint32_t line_number = 0;
int r, err;
int r;
f = fopen(filename, "re");
if (!f)
@@ -502,24 +502,23 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
break;
if (line[0] == ' ') {
r = log_syntax(NULL, LOG_WARNING, filename, line_number, SYNTHETIC_ERRNO(EINVAL),
"Match expected but got indented property \"%s\", ignoring line.", line);
log_syntax(NULL, LOG_WARNING, filename, line_number, 0,
"Match expected but got indented property \"%s\", ignoring line.", line);
break;
}
/* start of record, first match */
state = HW_MATCH;
err = strv_extend(&match_list, line);
if (err < 0)
return err;
r = strv_extend(&match_list, line);
if (r < 0)
return r;
break;
case HW_MATCH:
if (len == 0) {
r = log_syntax(NULL, LOG_WARNING, filename, line_number, SYNTHETIC_ERRNO(EINVAL),
"Property expected, ignoring record with no properties.");
log_syntax(NULL, LOG_WARNING, filename, line_number, 0,
"Property expected, ignoring record with no properties.");
state = HW_NONE;
match_list = strv_free(match_list);
break;
@@ -527,18 +526,15 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
if (line[0] != ' ') {
/* another match */
err = strv_extend(&match_list, line);
if (err < 0)
return err;
r = strv_extend(&match_list, line);
if (r < 0)
return r;
break;
}
/* first data */
state = HW_DATA;
err = insert_data(trie, match_list, line, filename, file_priority, line_number, compat);
if (err < 0)
r = err;
(void) insert_data(trie, match_list, line, filename, file_priority, line_number, compat);
break;
case HW_DATA:
@@ -550,16 +546,14 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
}
if (line[0] != ' ') {
r = log_syntax(NULL, LOG_WARNING, filename, line_number, SYNTHETIC_ERRNO(EINVAL),
"Property or empty line expected, got \"%s\", ignoring record.", line);
log_syntax(NULL, LOG_WARNING, filename, line_number, 0,
"Property or empty line expected, got \"%s\", ignoring record.", line);
state = HW_NONE;
match_list = strv_free(match_list);
break;
}
err = insert_data(trie, match_list, line, filename, file_priority, line_number, compat);
if (err < 0)
r = err;
(void) insert_data(trie, match_list, line, filename, file_priority, line_number, compat);
break;
};
}

View File

@@ -30,7 +30,7 @@ static size_t pe_header_size(const PeHeader *pe_header) {
return offsetof(PeHeader, optional) + le16toh(pe_header->pe.SizeOfOptionalHeader);
}
const IMAGE_DATA_DIRECTORY *pe_header_get_data_directory(
const IMAGE_DATA_DIRECTORY* pe_header_get_data_directory(
const PeHeader *h,
size_t i) {
@@ -42,7 +42,7 @@ const IMAGE_DATA_DIRECTORY *pe_header_get_data_directory(
return PE_HEADER_OPTIONAL_FIELD(h, DataDirectory) + i;
}
const IMAGE_SECTION_HEADER *pe_section_table_find(
const IMAGE_SECTION_HEADER* pe_section_table_find(
const IMAGE_SECTION_HEADER *sections,
size_t n_sections,
const char *name) {
@@ -58,7 +58,7 @@ const IMAGE_SECTION_HEADER *pe_section_table_find(
FOREACH_ARRAY(section, sections, n_sections)
if (memcmp(section->Name, name, n) == 0 &&
memeqzero(section->Name + n, sizeof(section->Name) - n))
(n == sizeof(sections[0].Name) || memeqzero(section->Name + n, sizeof(section->Name) - n)))
return section;
return NULL;

View File

@@ -138,9 +138,9 @@ bool pe_header_is_64bit(const PeHeader *h);
#define PE_HEADER_OPTIONAL_FIELD_OFFSET(h, field) \
(pe_header_is_64bit(h) ? offsetof(PeHeader, optional.pe32plus_##field) : offsetof(PeHeader, optional.pe32_##field))
const IMAGE_DATA_DIRECTORY *pe_header_get_data_directory(const PeHeader *h, size_t i);
const IMAGE_SECTION_HEADER *pe_header_find_section(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections, const char *name);
const IMAGE_SECTION_HEADER *pe_section_table_find(const IMAGE_SECTION_HEADER *sections, size_t n_sections, const char *name);
const IMAGE_DATA_DIRECTORY* pe_header_get_data_directory(const PeHeader *h, size_t i);
const IMAGE_SECTION_HEADER* pe_header_find_section(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections, const char *name);
const IMAGE_SECTION_HEADER* pe_section_table_find(const IMAGE_SECTION_HEADER *sections, size_t n_sections, const char *name);
int pe_load_headers(int fd, IMAGE_DOS_HEADER **ret_dos_header, PeHeader **ret_pe_header);