Skip to content

Commit 4a60127

Browse files
CassivsGabriellistiwai
authored andcommitted
ALSA: compress: Fix task creation error unwind
snd_compr_task_new() allocates the driver task before validating the returned DMA buffers and reserving file descriptors. When either of those later steps fails, the core frees its task wrapper and DMA-buffer references without calling the driver's task_free() callback. Any driver resources allocated by task_create() are therefore leaked. The dual-fd allocation path also jumps to cleanup without storing the negative get_unused_fd_flags() result in retval. Since retval still contains the successful task_create() return value, TASK_CREATE can incorrectly report success although the task was discarded. Preserve the fd allocation errors and call task_free() when failure occurs after a successful task_create() callback. Fixes: 0417715 ("ALSA: compress_offload: introduce accel operation mode") Fixes: 3d3f43f ("ALSA: compress_offload: improve file descriptors installation for dma-buf") Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260615-alsa-compress-task-unwind-v1-1-39e8ad3ddb27@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent c5e90e8 commit 4a60127

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

sound/core/compress_offload.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,15 +1083,18 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_
10831083
file descriptors are allocated before fd_install() */
10841084
if (!task->input || !task->input->file || !task->output || !task->output->file) {
10851085
retval = -EINVAL;
1086-
goto cleanup;
1086+
goto free_driver_task;
10871087
}
10881088
fd_i = get_unused_fd_flags(O_WRONLY|O_CLOEXEC);
1089-
if (fd_i < 0)
1090-
goto cleanup;
1089+
if (fd_i < 0) {
1090+
retval = fd_i;
1091+
goto free_driver_task;
1092+
}
10911093
fd_o = get_unused_fd_flags(O_RDONLY|O_CLOEXEC);
10921094
if (fd_o < 0) {
1095+
retval = fd_o;
10931096
put_unused_fd(fd_i);
1094-
goto cleanup;
1097+
goto free_driver_task;
10951098
}
10961099
/* keep dmabuf reference until freed with task free ioctl */
10971100
get_dma_buf(task->input);
@@ -1103,6 +1106,8 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_
11031106
list_add_tail(&task->list, &stream->runtime->tasks);
11041107
stream->runtime->total_tasks++;
11051108
return 0;
1109+
free_driver_task:
1110+
stream->ops->task_free(stream, task);
11061111
cleanup:
11071112
snd_compr_task_free(task);
11081113
return retval;

0 commit comments

Comments
 (0)