Skip to content

Commit

Permalink
Safe memory functions
Browse files Browse the repository at this point in the history
Introduce *x() wrappers for strdup(), malloc(), and calloc() which abort
on ENOMEM.

Fixes `-Wanalyzer-possible-null-dereference` warnings.
  • Loading branch information
martinpitt committed Sep 30, 2021
1 parent 92c8a00 commit ec6f986
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 21 deletions.
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ endif
preload_lib = shared_library('umockdev-preload',
['src/libumockdev-preload.c',
'src/debug.c',
'src/utils.c',
'src/ioctl_tree.c'],
c_args: ['-fvisibility=default'],
version: '0.0.0',
Expand All @@ -111,6 +112,7 @@ umockdev_lib = shared_library('umockdev',
'src/uevent_sender.c',
'src/ioctl_tree.vapi',
'src/ioctl_tree.c',
'src/utils.c',
'src/debug.c'],
vala_vapi: 'umockdev-1.0.vapi',
vala_gir: 'UMockdev-1.0.gir',
Expand Down Expand Up @@ -172,6 +174,7 @@ umockdev_record_exe = executable('umockdev-record',
'src/umockdev-spi.vala',
'src/ioctl_tree.vapi',
'src/ioctl_tree.c',
'src/utils.c',
'src/debug.c'],
dependencies: [glib, gobject, gio_unix, vapi_posix, vapi_config, vapi_ioctl, libpcap],
link_with: [umockdev_utils_lib],
Expand Down Expand Up @@ -238,6 +241,7 @@ endif
test('ioctl-tree', executable('test-ioctl-tree',
['tests/test-ioctl-tree.c',
'src/ioctl_tree.c',
'src/utils.c',
'src/debug.c'],
include_directories: include_directories('src'),
dependencies: [glib]))
Expand Down
3 changes: 2 additions & 1 deletion src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdio.h>

#include "debug.h"
#include "utils.h"

unsigned debug_categories = 0;

Expand All @@ -13,7 +14,7 @@ init_debug(void)
char *d_copy, *token;
if (d == NULL)
return;
d_copy = strdup(d);
d_copy = strdupx(d);
for (token = strtok(d_copy, " ,"); token; token = strtok(NULL, " ,")) {
if (strcmp (token, "all") == 0)
debug_categories = ~0;
Expand Down
23 changes: 7 additions & 16 deletions src/ioctl_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,14 @@
#include <linux/hidraw.h>

#include "debug.h"
#include "utils.h"
#include "ioctl_tree.h"

#define TRUE 1
#define FALSE 0

#define UNUSED __attribute__ ((unused))

static void *
callocx (size_t nmemb, size_t size)
{
void *r = calloc (nmemb, size);
if (r == NULL) {
perror ("failed to allocate memory");
abort ();
}
return r;
}

/***********************************
*
Expand Down Expand Up @@ -328,7 +319,7 @@ ioctl_node_list *
ioctl_node_list_new(void)
{
ioctl_node_list *l;
l = malloc(sizeof(ioctl_node_list));
l = mallocx(sizeof(ioctl_node_list));
l->n = 0;
l->capacity = 10;
l->items = callocx(sizeof(ioctl_tree *), l->capacity);
Expand Down Expand Up @@ -496,7 +487,7 @@ static void
ioctl_simplestruct_init_from_bin(ioctl_tree * node, const void *data)
{
DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_bin: %s(%X): size is %u bytes\n", node->type->name, (unsigned) node->id, (unsigned) NSIZE(node));
node->data = malloc(NSIZE(node));
node->data = mallocx(NSIZE(node));
memcpy(node->data, data, NSIZE(node));
}

Expand All @@ -507,7 +498,7 @@ ioctl_simplestruct_init_from_text(ioctl_tree * node, const char *data)
* correct length for data; this happens for variable length ioctls such as
* EVIOCGBIT */
size_t data_len = strlen(data) / 2;
node->data = malloc(data_len);
node->data = mallocx(data_len);

if (NSIZE(node) != data_len) {
DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_text: adjusting ioctl ID %X (size %u) to actual data length %zu\n",
Expand Down Expand Up @@ -570,7 +561,7 @@ ioctl_varlenstruct_init_from_bin(ioctl_tree * node, const void *data)
{
size_t size = node->type->get_data_size(node->id, data);
DBG(DBG_IOCTL_TREE, "ioctl_varlenstruct_init_from_bin: %s(%X): size is %zu bytes\n", node->type->name, (unsigned) node->id, size);
node->data = malloc(size);
node->data = mallocx(size);
memcpy(node->data, data, size);
}

Expand All @@ -579,7 +570,7 @@ ioctl_varlenstruct_init_from_text(ioctl_tree * node, const char *data)
{
size_t data_len = strlen(data) / 2;

node->data = malloc(data_len);
node->data = mallocx(data_len);

if (!read_hex(data, node->data, data_len)) {
fprintf(stderr, "ioctl_varlenstruct_init_from_text: failed to parse '%s'\n", data);
Expand Down Expand Up @@ -999,7 +990,7 @@ ioctl_type_get_by_name(const char *name, IOCTL_REQUEST_TYPE *out_id)
long offset = 0;

/* chop off real name from offset */
real_name = strdup(name);
real_name = strdupx(name);
parens = strchr(real_name, '(');
if (parens != NULL) {
*parens = '\0';
Expand Down
7 changes: 4 additions & 3 deletions src/libumockdev-preload.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@

#include "config.h"
#include "debug.h"
#include "utils.h"
#include "ioctl_tree.h"

/* fix missing O_TMPFILE on some systems */
Expand Down Expand Up @@ -483,9 +484,9 @@ ioctl_emulate_open(int fd, const char *dev_path, int must_exist)
}
}

fdinfo = malloc(sizeof(struct ioctl_fd_info));
fdinfo = mallocx(sizeof(struct ioctl_fd_info));
fdinfo->ioctl_sock = sock;
fdinfo->dev_path = strdup(dev_path);
fdinfo->dev_path = strdupx(dev_path);
fdinfo->is_default = is_default;
pthread_mutex_init(&fdinfo->sock_lock, NULL);

Expand Down Expand Up @@ -856,7 +857,7 @@ script_start_record(int fd, const char *logname, const char *recording_path, enu
}
}

srinfo = malloc(sizeof(struct script_record_info));
srinfo = mallocx(sizeof(struct script_record_info));
srinfo->log = log;
if (clock_gettime(CLOCK_MONOTONIC, &srinfo->time) < 0) {
fprintf(stderr, "libumockdev-preload: failed to clock_gettime: %m\n");
Expand Down
3 changes: 2 additions & 1 deletion src/uevent_sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include <libudev.h>

#include "utils.h"
#include "uevent_sender.h"

struct _uevent_sender {
Expand All @@ -49,7 +50,7 @@ uevent_sender_open(const char *rootpath)
perror("uevent_sender_open: cannot allocate struct");
abort();
}
s->rootpath = strdup(rootpath);
s->rootpath = strdupx(rootpath);
s->udev = udev_new();
snprintf(s->socket_glob, sizeof(s->socket_glob), "%s/event[0-9]*", rootpath);

Expand Down
40 changes: 40 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "utils.h"

static void
abort_errno (const char *msg)
{
perror (msg);
abort ();
}

void *
callocx (size_t nmemb, size_t size)
{
void *r = calloc (nmemb, size);
if (r == NULL)
abort_errno ("failed to allocate memory");
return r;
}

void *
mallocx (size_t size)
{
void *r = malloc (size);
if (r == NULL)
abort_errno ("failed to allocate memory");
return r;
}


char *
strdupx (const char *s)
{
char *r = strdup (s);
if (r == NULL)
abort_errno ("failed to allocate memory for strdup");
return r;
}
6 changes: 6 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

/* variants of glibc functions that abort() on ENOMEM */
void *mallocx (size_t size);
void *callocx (size_t nmemb, size_t size);
char *strdupx (const char *s);

0 comments on commit ec6f986

Please sign in to comment.