swresample: Check user chlayout in swr_set_matrix()

All callers in FFmpeg check this already, but it is a public
function that can plausibly be given more channels.
In which case out of array writes would occur

This is likely a regression from when channel layouts where extended
to support more than 64 channels

Found-by: 이동준 <ldj6192@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2026-02-03 22:06:24 +01:00
parent 0d59620bff
commit 906e3edc70
3 changed files with 21 additions and 13 deletions

View File

@@ -66,7 +66,10 @@ int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
{
int nb_in, nb_out, in, out;
if (!s || s->in_convert) // s needs to be allocated but not initialized
if (!s || s->in_convert || // s needs to be allocated but not initialized
swri_check_chlayout(s, &s->user_in_chlayout , "input") ||
swri_check_chlayout(s, &s->user_out_chlayout, "output")
)
return AVERROR(EINVAL);
memset(s->matrix, 0, sizeof(s->matrix));

View File

@@ -30,6 +30,20 @@
#define ALIGN 32
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name) {
char l1[1024];
int ret;
if (!(ret = av_channel_layout_check(chl)) || chl->nb_channels > SWR_CH_MAX) {
if (ret)
av_channel_layout_describe(chl, l1, sizeof(l1));
av_log(s, AV_LOG_WARNING, "%s channel layout \"%s\" is invalid or unsupported.\n", name, ret ? l1 : "");
return AVERROR(EINVAL);
}
return 0;
}
int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
if(!s || s->in_convert) // s needs to be allocated but not initialized
return AVERROR(EINVAL);
@@ -162,19 +176,9 @@ av_cold int swr_init(struct SwrContext *s){
s->out.ch_count = s-> user_out_chlayout.nb_channels;
s-> in.ch_count = s-> user_in_chlayout.nb_channels;
if (!(ret = av_channel_layout_check(&s->user_in_chlayout)) || s->user_in_chlayout.nb_channels > SWR_CH_MAX) {
if (ret)
av_channel_layout_describe(&s->user_in_chlayout, l1, sizeof(l1));
av_log(s, AV_LOG_WARNING, "Input channel layout \"%s\" is invalid or unsupported.\n", ret ? l1 : "");
if (swri_check_chlayout(s, &s->user_in_chlayout , "input") ||
swri_check_chlayout(s, &s->user_out_chlayout, "output"))
return AVERROR(EINVAL);
}
if (!(ret = av_channel_layout_check(&s->user_out_chlayout)) || s->user_out_chlayout.nb_channels > SWR_CH_MAX) {
if (ret)
av_channel_layout_describe(&s->user_out_chlayout, l2, sizeof(l2));
av_log(s, AV_LOG_WARNING, "Output channel layout \"%s\" is invalid or unsupported.\n", ret ? l2 : "");
return AVERROR(EINVAL);
}
ret = av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout);
ret |= av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout);

View File

@@ -198,6 +198,7 @@ struct SwrContext {
av_warn_unused_result
int swri_realloc_audio(AudioData *a, int count);
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name);
void swri_noise_shaping_int16 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);