mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-30 06:46:49 -04:00
security: fix integer overflow in pw-cli param info allocation
Memory Safety: High Three places in pw-cli allocated param info arrays using malloc(n_params * sizeof(struct spa_param_info)) where n_params comes from remote protocol data. The multiplication can overflow, causing a small buffer to be allocated while n_params remains large. Later code iterating over n_params entries would read past the allocated buffer. Fixed by using calloc(n_params, sizeof(...)) which internally checks for multiplication overflow and returns NULL on failure. Also added NULL checks and proper fallback when allocation fails. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2fee779161
commit
bf614354cc
1 changed files with 24 additions and 12 deletions
|
|
@ -1140,11 +1140,15 @@ static void session_event_info(void *data,
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
info->id = update->id;
|
info->id = update->id;
|
||||||
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
|
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
|
||||||
info->n_params = update->n_params;
|
|
||||||
free(info->params);
|
free(info->params);
|
||||||
info->params = malloc(info->n_params * sizeof(struct spa_param_info));
|
info->params = calloc(update->n_params, sizeof(struct spa_param_info));
|
||||||
memcpy(info->params, update->params,
|
if (update->n_params > 0 && info->params == NULL) {
|
||||||
info->n_params * sizeof(struct spa_param_info));
|
info->n_params = 0;
|
||||||
|
} else {
|
||||||
|
info->n_params = update->n_params;
|
||||||
|
memcpy(info->params, update->params,
|
||||||
|
info->n_params * sizeof(struct spa_param_info));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
|
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
|
||||||
pw_properties_free ((struct pw_properties *)info->props);
|
pw_properties_free ((struct pw_properties *)info->props);
|
||||||
|
|
@ -1196,11 +1200,15 @@ static void endpoint_event_info(void *data,
|
||||||
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_SESSION)
|
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_SESSION)
|
||||||
info->session_id = update->session_id;
|
info->session_id = update->session_id;
|
||||||
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
|
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
|
||||||
info->n_params = update->n_params;
|
|
||||||
free(info->params);
|
free(info->params);
|
||||||
info->params = malloc(info->n_params * sizeof(struct spa_param_info));
|
info->params = calloc(update->n_params, sizeof(struct spa_param_info));
|
||||||
memcpy(info->params, update->params,
|
if (update->n_params > 0 && info->params == NULL) {
|
||||||
info->n_params * sizeof(struct spa_param_info));
|
info->n_params = 0;
|
||||||
|
} else {
|
||||||
|
info->n_params = update->n_params;
|
||||||
|
memcpy(info->params, update->params,
|
||||||
|
info->n_params * sizeof(struct spa_param_info));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
|
if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
|
||||||
pw_properties_free ((struct pw_properties *)info->props);
|
pw_properties_free ((struct pw_properties *)info->props);
|
||||||
|
|
@ -1245,11 +1253,15 @@ static void endpoint_stream_event_info(void *data,
|
||||||
info->name = update->name ? strdup(update->name) : NULL;
|
info->name = update->name ? strdup(update->name) : NULL;
|
||||||
|
|
||||||
if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS) {
|
if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS) {
|
||||||
info->n_params = update->n_params;
|
|
||||||
free(info->params);
|
free(info->params);
|
||||||
info->params = malloc(info->n_params * sizeof(struct spa_param_info));
|
info->params = calloc(update->n_params, sizeof(struct spa_param_info));
|
||||||
memcpy(info->params, update->params,
|
if (update->n_params > 0 && info->params == NULL) {
|
||||||
info->n_params * sizeof(struct spa_param_info));
|
info->n_params = 0;
|
||||||
|
} else {
|
||||||
|
info->n_params = update->n_params;
|
||||||
|
memcpy(info->params, update->params,
|
||||||
|
info->n_params * sizeof(struct spa_param_info));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS) {
|
if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS) {
|
||||||
pw_properties_free ((struct pw_properties *)info->props);
|
pw_properties_free ((struct pw_properties *)info->props);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue