mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
spa: param: add size checks for spa_audio_info* structs
In the API that take struct size for spa_audio_info*, also check the struct size.
This commit is contained in:
parent
8a23b13798
commit
c6d0b364ab
7 changed files with 197 additions and 3 deletions
|
|
@ -46,18 +46,58 @@ extern "C" {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
SPA_API_AUDIO_FORMAT_UTILS bool
|
||||
spa_format_audio_ext_valid_size(uint32_t media_subtype, size_t size)
|
||||
{
|
||||
switch (media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
return size >= offsetof(struct spa_audio_info, info.raw) &&
|
||||
SPA_AUDIO_INFO_RAW_VALID_SIZE(size - offsetof(struct spa_audio_info, info.raw));
|
||||
|
||||
#define _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(format) \
|
||||
case SPA_MEDIA_SUBTYPE_ ## format: \
|
||||
return size >= offsetof(struct spa_audio_info, info.format) + sizeof(struct spa_audio_info_ ## format);
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dsp)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(iec958)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dsd)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(mp3)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(aac)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(vorbis)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(wma)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ra)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(amr)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(alac)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(flac)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ape)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ac3)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(eac3)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(truehd)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dts)
|
||||
_SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(mpegh)
|
||||
#undef _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SPA_API_AUDIO_FORMAT_UTILS int
|
||||
spa_format_audio_ext_parse(const struct spa_pod *format, struct spa_audio_info *info, size_t size)
|
||||
{
|
||||
int res;
|
||||
uint32_t media_type, media_subtype;
|
||||
|
||||
if ((res = spa_format_parse(format, &info->media_type, &info->media_subtype)) < 0)
|
||||
if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0)
|
||||
return res;
|
||||
|
||||
if (info->media_type != SPA_MEDIA_TYPE_audio)
|
||||
if (media_type != SPA_MEDIA_TYPE_audio)
|
||||
return -EINVAL;
|
||||
|
||||
switch (info->media_subtype) {
|
||||
if (!spa_format_audio_ext_valid_size(media_subtype, size))
|
||||
return -EINVAL;
|
||||
|
||||
info->media_type = media_type;
|
||||
info->media_subtype = media_subtype;
|
||||
|
||||
switch (media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
return spa_format_audio_raw_ext_parse(format, &info->info.raw,
|
||||
size - offsetof(struct spa_audio_info, info.raw));
|
||||
|
|
@ -109,6 +149,11 @@ SPA_API_AUDIO_FORMAT_UTILS struct spa_pod *
|
|||
spa_format_audio_ext_build(struct spa_pod_builder *builder, uint32_t id,
|
||||
const struct spa_audio_info *info, size_t size)
|
||||
{
|
||||
if (!spa_format_audio_ext_valid_size(info->media_subtype, size)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (info->media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
return spa_format_audio_raw_ext_build(builder, id, &info->info.raw,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ struct spa_audio_info {
|
|||
struct spa_audio_info_dts dts;
|
||||
struct spa_audio_info_mpegh mpegh;
|
||||
} info;
|
||||
|
||||
/* padding follows here when info has flexible size */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ spa_audio_info_raw_ext_update(struct spa_audio_info_raw *info, size_t size,
|
|||
{
|
||||
uint32_t v;
|
||||
uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size);
|
||||
|
||||
if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size))
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_streq(key, SPA_KEY_AUDIO_FORMAT)) {
|
||||
if (force || info->format == 0)
|
||||
info->format = (enum spa_audio_format)spa_type_audio_format_from_short_name(val);
|
||||
|
|
@ -100,6 +104,9 @@ spa_audio_info_raw_ext_init_dict_keys_va(struct spa_audio_info_raw *info, size_t
|
|||
{
|
||||
int res;
|
||||
|
||||
if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size))
|
||||
return -EINVAL;
|
||||
|
||||
memset(info, 0, size);
|
||||
SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
if (dict) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ spa_format_audio_raw_ext_parse(const struct spa_pod *format, struct spa_audio_in
|
|||
int res;
|
||||
uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size);
|
||||
|
||||
if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size))
|
||||
return -EINVAL;
|
||||
|
||||
info->flags = 0;
|
||||
res = spa_pod_parse_object(format,
|
||||
SPA_TYPE_OBJECT_Format, NULL,
|
||||
|
|
@ -64,6 +67,11 @@ spa_format_audio_raw_ext_build(struct spa_pod_builder *builder, uint32_t id,
|
|||
struct spa_pod_frame f;
|
||||
uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size);
|
||||
|
||||
if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id);
|
||||
spa_pod_builder_add(builder,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
|
|
|
|||
|
|
@ -293,6 +293,8 @@ struct spa_audio_info_raw {
|
|||
|
||||
#define SPA_AUDIO_INFO_RAW_MAX_POSITION(size) (((size)-offsetof(struct spa_audio_info_raw,position))/sizeof(uint32_t))
|
||||
|
||||
#define SPA_AUDIO_INFO_RAW_VALID_SIZE(size) ((size) >= offsetof(struct spa_audio_info_raw, position))
|
||||
|
||||
|
||||
#define SPA_KEY_AUDIO_FORMAT "audio.format" /**< an audio format as string,
|
||||
* Ex. "S16LE" */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue