[bug report] ASoC: topology: fix endianness issues

Ranjani Sridharan ranjani.sridharan at linux.intel.com
Wed Dec 9 18:32:33 CET 2020


On Wed, 2020-12-09 at 17:19 +0100, Amadeusz Sławiński wrote:
> On 12/9/2020 3:30 PM, Pierre-Louis Bossart wrote:
> > Thanks Dan for the bug report.
> > 
> > On 12/9/20 12:53 AM, Dan Carpenter wrote:
> > > [ This bug is way older than your patch but you might know the
> > > answer.
> > >    -dan ]
> > > 
> > > Hello Pierre-Louis Bossart,
> > > 
> > > The patch 5aebe7c7f9c2: "ASoC: topology: fix endianness issues"
> > > from
> > > Apr 4, 2019, leads to the following static checker warning:
> > > 
> > >     sound/soc/soc-topology.c:903 soc_tplg_denum_create_values()
> > >     warn: potential pointer math issue ('se-
> > > >dobj.control.dvalues' is 
> > > a 64 bit pointer)
> > > 
> > > sound/soc/soc-topology.c
> > >     887  static int soc_tplg_denum_create_values(struct soc_tplg 
> > > *tplg, struct soc_enum *se,
> > >     888                                          struct 
> > > snd_soc_tplg_enum_control *ec)
> > >     889  {
> > >     890          int i;
> > >     891
> > >     892          if (le32_to_cpu(ec->items) > sizeof(*ec-
> > > >values))
> > > 
> > > The warning is from this line where Smatch starts to think that
> > > "ec->items" is the number of bytes, but later in the function we
> > > treat
> > > it was the number of elements.
> > > 
> > > I do think probably this should be if:
> > > 
> > >         if (le32_to_cpu(ec->items) > ARRAY_SIZE(ec->values))
> > >             return -EINVAL;
> > > 
> > > The ec->values[] is an array of u32:
> > > 
> > >     __le32 values[SND_SOC_TPLG_NUM_TEXTS * 
> > > SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
> > > 
> > > so this code will return -EINVAL for anything larger than 4. 
> > > Changing
> > > it to ARRAY_SIZE() would raise the limit to 176.
> > 
> > I agree with your analysis, even in the initial code the pattern
> > was
> > 
> > if (ec->items > sizeof(*ec->values))
> > 
> > and that's indeed a clear confusion between number of elements and
> > total 
> > number of bytes.
> > 
> > Ranjani and Amadeusz are more familiar than me with the topology
> > code, 
> > let's see if they concur?
> > 
> 
> Yes, seems about right, we can also replace devm_kzalloc below with 
> devm_kcalloc to make it even more clear that we are dealing with
> array.
> 
> 
> On related note looking at the UAPI header... I noticed:
> 
> struct snd_soc_tplg_enum_control {
> 	(...)
> 	char
> texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
> 	__le32 values[SND_SOC_TPLG_NUM_TEXTS *
> SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
> 
> which means that there is 16 names and then there is an array of
> values, 
> which seems somehow oversized compared to names... not sure why we 
> multiply it by maximum length of name and then divide...
> 
> I guess we could change it to something like:
> __le32 values[SND_SOC_TPLG_NUM_TEXTS];
> __le32 reserved[160];
> 
> I'm not sure if we want to change it, but I guess it is something to 
> keep in the back of the head. Quite frankly looking at it bit more
> I'm 
> starting to think that those values from topology are not used
> anywhere 
> after being assigned in the function from which this investigation 
> started, simple grep for "dvalues" reports nothing more than 
> soc-topology.c file, but I might have missed something.
> 
> Another thing which I started wondering about, why we even keep
> those 
> values in "se->dobj.control", can't we just use "se" directly, as it 
> seems to have required fields.
> 
> I guess I will look at it again tomorrow when I have a bit more
> fresh 
> head, but I guess for now ARRAY_SIZE and devm_kcalloc change seems
> good 
> to me, as the rest will have less to do with "array" type and more
> with 
> general logic of parsing things.

Would this be a simpler check than using ARRAY_SIZE?

if (le32_to_cpu(ec->items) > SND_SOC_TPLG_NUM_TEXTS )
		return -EINVAL;

Thanks,Ranjani



More information about the Alsa-devel mailing list