security: add missing NULL checks after strdup in modemmanager

Memory Safety: Medium

Four strdup() calls in the ModemManager Bluetooth integration had no
NULL checks, which could lead to NULL pointer dereferences under
memory pressure:

- mm_parse_call_properties(): call->number assignment
- mm_parse_interfaces(): this->modem.path assignment
- mm_filter_cb(): call_object->path assignment (also leaked calloc
  on failure)
- mm_register(): this->allowed_modem_device assignment

Each site now checks for NULL and handles the failure appropriately
for its context (early return, goto cleanup, or return error).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Wim Taymans 2026-04-29 11:34:37 +02:00
parent 9a4e0e4c85
commit dcf28ff248

View file

@ -141,9 +141,10 @@ static void mm_get_call_properties_reply(DBusPendingCall *pending, void *user_da
dbus_message_iter_get_basic(&value_i, &number); dbus_message_iter_get_basic(&value_i, &number);
spa_log_debug(this->log, "Call number: %s", number); spa_log_debug(this->log, "Call number: %s", number);
if (call->number) free(call->number);
free(call->number);
call->number = strdup(number); call->number = strdup(number);
if (call->number == NULL)
return;
} else if (spa_streq(key, MM_CALL_PROPERTY_STATE)) { } else if (spa_streq(key, MM_CALL_PROPERTY_STATE)) {
int clcc_state; int clcc_state;
@ -363,6 +364,8 @@ static DBusHandlerResult mm_parse_interfaces(struct impl *this, DBusMessageIter
} }
} }
this->modem.path = strdup(path); this->modem.path = strdup(path);
if (this->modem.path == NULL)
goto next;
} else if (!spa_streq(this->modem.path, path)) { } else if (!spa_streq(this->modem.path, path)) {
spa_log_debug(this->log, "A modem is already registered"); spa_log_debug(this->log, "A modem is already registered");
goto next; goto next;
@ -618,6 +621,10 @@ static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void
return DBUS_HANDLER_RESULT_NEED_MEMORY; return DBUS_HANDLER_RESULT_NEED_MEMORY;
call_object->this = this; call_object->this = this;
call_object->path = strdup(path); call_object->path = strdup(path);
if (call_object->path == NULL) {
free(call_object);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
spa_list_append(&this->call_list, &call_object->link); spa_list_append(&this->call_list, &call_object->link);
m2 = dbus_message_new_method_call(MM_DBUS_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "GetAll"); m2 = dbus_message_new_method_call(MM_DBUS_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "GetAll");
@ -1113,8 +1120,11 @@ void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_d
this->conn = dbus_connection; this->conn = dbus_connection;
this->ops = ops; this->ops = ops;
this->user_data = user_data; this->user_data = user_data;
if (modem_device_str && !spa_streq(modem_device_str, "any")) if (modem_device_str && !spa_streq(modem_device_str, "any")) {
this->allowed_modem_device = strdup(modem_device_str); this->allowed_modem_device = strdup(modem_device_str);
if (this->allowed_modem_device == NULL)
return NULL;
}
spa_list_init(&this->call_list); spa_list_init(&this->call_list);
this->pts = pts; this->pts = pts;