fix: Fix potential error scenarios

Configuring the build with CFLAGS="-O2 -g -fanalyzer", we ran into some
build errors, which we address in this commit.

First off, GCC identified a false positive file descriptor leak in
x52d_client.c, this instance is suppressed to avoid breaking the build.

There was a bug in x52d_clock.c, where if the original timezone could
not have a copy due to malloc failure, it would fail when resetting the
TZ environment. This is fixed by ensuring the copy is valid.

Finally, there was a potential NULL pointer dereference if the pinelog
module messes up the log levels, and the lmap_get_string method ends up
returning a NULL which was passed to the DATA macro. This is fixed by
checking for NULL and handling it in case of failure.
pull/60/head
nirenjan 2026-03-09 00:07:02 -07:00
parent 2be7792024
commit a17312dcbc
3 changed files with 30 additions and 5 deletions

View File

@ -27,6 +27,11 @@ bool x52d_client_register(int client_fd[X52D_MAX_CLIENTS], int sock_fd)
int fd;
int i;
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wanalyzer-fd-leak"
#endif
fd = accept(sock_fd, NULL, NULL);
if (fd < 0) {
PINELOG_ERROR(_("Error accepting client connection on socket fd %d: %s"),
@ -40,6 +45,11 @@ bool x52d_client_register(int client_fd[X52D_MAX_CLIENTS], int sock_fd)
goto error;
}
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
for (i = 0; i < X52D_MAX_CLIENTS; i++) {
if (client_fd[i] == INVALID_CLIENT) {
PINELOG_TRACE("Accepted client %d on socket %d, slot %d", fd, sock_fd, i);

View File

@ -97,8 +97,11 @@ cleanup:
if (orig_tz == NULL) {
unsetenv("TZ");
} else {
setenv("TZ", orig_tz_copy, true);
free(orig_tz_copy);
// If the copy is NULL, then we didn't change TZ, so don't bother
if (orig_tz_copy != NULL) {
setenv("TZ", orig_tz_copy, true);
free(orig_tz_copy);
}
}
if (new_tz != NULL) {

View File

@ -239,6 +239,19 @@ static const char *lmap_get_string(const struct level_map *map, int level)
return NULL;
}
#define DATA_LMAP(map, level, resp) do {\
int input_level_ ## __LINE__ = level; \
const char *lmap_level_ ## __LINE__ = lmap_get_string(map, input_level_ ## __LINE__); \
char lmap_unknown_level ## __LINE__[32] = {0}; \
if (lmap_level_ ## __LINE__ == NULL) { \
snprintf(lmap_unknown_level ## __LINE__, sizeof(lmap_unknown_level ## __LINE__), \
"unknown (%d)", input_level_ ## __LINE__); \
lmap_level_ ## __LINE__ = lmap_unknown_level ## __LINE__; \
} \
DATA(resp, lmap_level_ ## __LINE__); \
} while(0)
static int array_find_index(const char **array, int nmemb, const char *string)
{
int i;
@ -287,14 +300,13 @@ static void cmd_logging(char *buffer, int *buflen, int argc, char **argv)
// logging show [module]
MATCH(1, "show") {
if (argc == 2) {
// Show default logging level
DATA("global", lmap_get_string(loglevels, pinelog_get_level()));
DATA_LMAP(loglevels, pinelog_get_level(), "global");
} else if (argc == 3) {
int module = array_find_index(modules, X52D_MOD_MAX, argv[2]);
if (module == X52D_MOD_MAX) {
ERR_fmt("Invalid module '%s'", argv[2]);
} else {
DATA(argv[2], lmap_get_string(loglevels, pinelog_get_module_level(module)));
DATA_LMAP(loglevels, pinelog_get_module_level(module), argv[2]);
}
} else {
ERR_fmt("Unexpected arguments for 'logging show' command; got %d, expected 2 or 3", argc);