bsps/shared/gpio: Fix group define leaks

In rtems_gpio_define_pin_group(), several malloc() calls did not
check their return values. This could lead to NULL pointer
dereferences in later initialization steps.

The previous error handling also leaked memory and hardware pin
resources if an intermediate step.

This patch refactors the error handling path to address these issues.
This commit is contained in:
Yang Zhang
2026-06-18 16:48:55 +00:00
committed by Gedare Bloom
parent 7e68b06641
commit 5661c6531f
+55 -9
View File
@@ -696,11 +696,23 @@ rtems_gpio_group *rtems_gpio_create_pin_group(void)
return group;
}
static void release_group_allocations(rtems_gpio_group *group)
{
free(group->digital_inputs);
free(group->digital_outputs);
free(group->bsp_specific_pins);
group->digital_inputs = NULL;
group->digital_outputs = NULL;
group->bsp_specific_pins = NULL;
}
rtems_status_code rtems_gpio_define_pin_group(
const rtems_gpio_group_definition *group_definition,
rtems_gpio_group *group
) {
rtems_status_code sc;
rtems_status_code release_sc;
if ( group_definition == NULL || group == NULL ) {
return RTEMS_UNSATISFIED;
@@ -714,12 +726,21 @@ rtems_status_code rtems_gpio_define_pin_group(
return RTEMS_UNSATISFIED;
}
group->digital_inputs = NULL;
group->digital_outputs = NULL;
group->bsp_specific_pins = NULL;
group->input_count = group_definition->input_count;
if ( group->input_count > 0 ) {
group->digital_inputs =
(uint32_t *) malloc(group->input_count * sizeof(uint32_t));
if ( group->digital_inputs == NULL ) {
release_group_allocations(group);
return RTEMS_NO_MEMORY;
}
/* Evaluate if the pins that will constitute the group are available and
* that pins with the same function within the group all belong
* to the same pin group. */
@@ -731,18 +752,20 @@ rtems_status_code rtems_gpio_define_pin_group(
);
if ( sc != RTEMS_SUCCESSFUL ) {
release_group_allocations(group);
return sc;
}
}
else {
group->digital_inputs = NULL;
}
group->output_count = group_definition->output_count;
if ( group->output_count > 0 ) {
group->digital_outputs =
(uint32_t *) malloc(group->output_count * sizeof(uint32_t));
if ( group->digital_outputs == NULL ) {
release_group_allocations(group);
return RTEMS_NO_MEMORY;
}
sc = check_same_bank_and_availability(
group_definition->digital_outputs,
@@ -752,12 +775,10 @@ rtems_status_code rtems_gpio_define_pin_group(
);
if ( sc != RTEMS_SUCCESSFUL ) {
release_group_allocations(group);
return sc;
}
}
else {
group->digital_outputs = NULL;
}
group->bsp_specific_pin_count = group_definition->bsp_specific_pin_count;
@@ -768,6 +789,11 @@ rtems_status_code rtems_gpio_define_pin_group(
sizeof(uint32_t)
);
if ( group->bsp_specific_pins == NULL ) {
release_group_allocations(group);
return RTEMS_NO_MEMORY;
}
sc = check_same_bank_and_availability(
group_definition->bsp_specifics,
group->bsp_specific_pin_count,
@@ -776,12 +802,10 @@ rtems_status_code rtems_gpio_define_pin_group(
);
if ( sc != RTEMS_SUCCESSFUL ) {
release_group_allocations(group);
return sc;
}
}
else {
group->bsp_specific_pins = NULL;
}
/* Request the pins. */
sc = gpio_multi_select(
@@ -791,6 +815,7 @@ rtems_status_code rtems_gpio_define_pin_group(
);
if ( sc != RTEMS_SUCCESSFUL ) {
release_group_allocations(group);
return RTEMS_UNSATISFIED;
}
@@ -808,6 +833,7 @@ rtems_status_code rtems_gpio_define_pin_group(
_Assert ( sc == RTEMS_SUCCESSFUL );
release_group_allocations(group);
return RTEMS_UNSATISFIED;
}
@@ -832,6 +858,7 @@ rtems_status_code rtems_gpio_define_pin_group(
_Assert ( sc == RTEMS_SUCCESSFUL );
release_group_allocations(group);
return RTEMS_UNSATISFIED;
}
@@ -839,6 +866,25 @@ rtems_status_code rtems_gpio_define_pin_group(
sc = CREATE_LOCK(rtems_build_name('G', 'R', 'P', 'L'), &group->group_lock);
if ( sc != RTEMS_SUCCESSFUL ) {
release_sc = rtems_gpio_release_multiple_pins(
group_definition->digital_inputs,
group_definition->input_count
);
_Assert( release_sc == RTEMS_SUCCESSFUL );
release_sc = rtems_gpio_release_multiple_pins(
group_definition->digital_outputs,
group_definition->output_count
);
_Assert( release_sc == RTEMS_SUCCESSFUL );
release_sc = rtems_gpio_release_multiple_pins(
group_definition->bsp_specifics,
group_definition->bsp_specific_pin_count
);
_Assert( release_sc == RTEMS_SUCCESSFUL );
release_group_allocations(group);
return sc;
}