[bug report] ASoC: topology: Add support for multiple kcontrol types to a widget

Dan Carpenter dan.carpenter at oracle.com
Wed May 19 10:22:33 CEST 2021


Hello Jaska Uimonen,

The patch d29d41e28eea: "ASoC: topology: Add support for multiple
kcontrol types to a widget" from May 7, 2021, leads to the following
static checker warning:

	sound/soc/soc-topology.c:1559 soc_tplg_dapm_widget_create()
	error: uninitialized symbol 'kcontrol_type'.

sound/soc/soc-topology.c
  1418  static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
  1419          struct snd_soc_tplg_dapm_widget *w)
  1420  {
  1421          struct snd_soc_dapm_context *dapm = &tplg->comp->dapm;
  1422          struct snd_soc_dapm_widget template, *widget;
  1423          struct snd_soc_tplg_ctl_hdr *control_hdr;
  1424          struct snd_soc_card *card = tplg->comp->card;
  1425          unsigned int *kcontrol_type;
  1426          struct snd_kcontrol_new *kc;
  1427          int mixer_count = 0;
  1428          int bytes_count = 0;
  1429          int enum_count = 0;
  1430          int ret = 0;
  1431          int i;
  1432  
  1433          if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
  1434                  SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
  1435                  return -EINVAL;
  1436          if (strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
  1437                  SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
  1438                  return -EINVAL;
  1439  
  1440          dev_dbg(tplg->dev, "ASoC: creating DAPM widget %s id %d\n",
  1441                  w->name, w->id);
  1442  
  1443          memset(&template, 0, sizeof(template));
  1444  
  1445          /* map user to kernel widget ID */
  1446          template.id = get_widget_id(le32_to_cpu(w->id));
  1447          if ((int)template.id < 0)
  1448                  return template.id;
  1449  
  1450          /* strings are allocated here, but used and freed by the widget */
  1451          template.name = kstrdup(w->name, GFP_KERNEL);
  1452          if (!template.name)
  1453                  return -ENOMEM;
  1454          template.sname = kstrdup(w->sname, GFP_KERNEL);
  1455          if (!template.sname) {
  1456                  ret = -ENOMEM;
  1457                  goto err;
  1458          }
  1459          template.reg = le32_to_cpu(w->reg);
  1460          template.shift = le32_to_cpu(w->shift);
  1461          template.mask = le32_to_cpu(w->mask);
  1462          template.subseq = le32_to_cpu(w->subseq);
  1463          template.on_val = w->invert ? 0 : 1;
  1464          template.off_val = w->invert ? 1 : 0;
  1465          template.ignore_suspend = le32_to_cpu(w->ignore_suspend);
  1466          template.event_flags = le16_to_cpu(w->event_flags);
  1467          template.dobj.index = tplg->index;
  1468  
  1469          tplg->pos +=
  1470                  (sizeof(struct snd_soc_tplg_dapm_widget) +
  1471                   le32_to_cpu(w->priv.size));
  1472  
  1473          if (w->num_kcontrols == 0) {
  1474                  template.num_kcontrols = 0;
  1475                  goto widget;

This patch changed kcontrol_type to a pointer.  Originally if we hit
this goto kcontrol_type was zero but now it's uninitialized.  This will
cause a runtime error with UBSan even if it isn't a real bug.

  1476          }
  1477  
  1478          control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
  1479          dev_dbg(tplg->dev, "ASoC: template %s has %d controls of type %x\n",
  1480                  w->name, w->num_kcontrols, control_hdr->type);
  1481  
  1482          template.num_kcontrols = le32_to_cpu(w->num_kcontrols);
  1483          kc = devm_kcalloc(tplg->dev, le32_to_cpu(w->num_kcontrols), sizeof(*kc), GFP_KERNEL);
  1484          if (!kc)
  1485                  goto err;
  1486  
  1487          kcontrol_type = devm_kcalloc(tplg->dev, le32_to_cpu(w->num_kcontrols), sizeof(unsigned int),
  1488                                       GFP_KERNEL);
  1489          if (!kcontrol_type)
  1490                  goto err;
  1491  
  1492          for (i = 0; i < w->num_kcontrols; i++) {
  1493                  control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
  1494                  switch (le32_to_cpu(control_hdr->ops.info)) {
  1495                  case SND_SOC_TPLG_CTL_VOLSW:
  1496                  case SND_SOC_TPLG_CTL_STROBE:
  1497                  case SND_SOC_TPLG_CTL_VOLSW_SX:
  1498                  case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
  1499                  case SND_SOC_TPLG_CTL_RANGE:
  1500                  case SND_SOC_TPLG_DAPM_CTL_VOLSW:
  1501                          /* volume mixer */
  1502                          kc[i].index = mixer_count;
  1503                          kcontrol_type[i] = SND_SOC_TPLG_TYPE_MIXER;
  1504                          mixer_count++;
  1505                          ret = soc_tplg_dapm_widget_dmixer_create(tplg, &kc[i]);
  1506                          if (ret < 0)
  1507                                  goto hdr_err;
  1508                          break;
  1509                  case SND_SOC_TPLG_CTL_ENUM:
  1510                  case SND_SOC_TPLG_CTL_ENUM_VALUE:
  1511                  case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
  1512                  case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
  1513                  case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
  1514                          /* enumerated mixer */
  1515                          kc[i].index = enum_count;
  1516                          kcontrol_type[i] = SND_SOC_TPLG_TYPE_ENUM;
  1517                          enum_count++;
  1518                          ret = soc_tplg_dapm_widget_denum_create(tplg, &kc[i]);
  1519                          if (ret < 0)
  1520                                  goto hdr_err;
  1521                          break;
  1522                  case SND_SOC_TPLG_CTL_BYTES:
  1523                          /* bytes control */
  1524                          kc[i].index = bytes_count;
  1525                          kcontrol_type[i] = SND_SOC_TPLG_TYPE_BYTES;
  1526                          bytes_count++;
  1527                          ret = soc_tplg_dapm_widget_dbytes_create(tplg, &kc[i]);
  1528                          if (ret < 0)
  1529                                  goto hdr_err;
  1530                          break;
  1531                  default:
  1532                          dev_err(tplg->dev, "ASoC: invalid widget control type %d:%d:%d\n",
  1533                                  control_hdr->ops.get, control_hdr->ops.put,
  1534                                  le32_to_cpu(control_hdr->ops.info));
  1535                          ret = -EINVAL;
  1536                          goto hdr_err;
  1537                  }
  1538          }
  1539  
  1540          template.kcontrol_news = kc;
  1541  
  1542  widget:
  1543          ret = soc_tplg_widget_load(tplg, &template, w);
  1544          if (ret < 0)
  1545                  goto hdr_err;
  1546  
  1547          /* card dapm mutex is held by the core if we are loading topology
  1548           * data during sound card init. */
  1549          if (card->instantiated)
  1550                  widget = snd_soc_dapm_new_control(dapm, &template);
  1551          else
  1552                  widget = snd_soc_dapm_new_control_unlocked(dapm, &template);
  1553          if (IS_ERR(widget)) {
  1554                  ret = PTR_ERR(widget);
  1555                  goto hdr_err;
  1556          }
  1557  
  1558          widget->dobj.type = SND_SOC_DOBJ_WIDGET;
  1559          widget->dobj.widget.kcontrol_type = kcontrol_type;
                                                    ^^^^^^^^^^^^^^

  1560          widget->dobj.ops = tplg->ops;
  1561          widget->dobj.index = tplg->index;
  1562          list_add(&widget->dobj.list, &tplg->comp->dobj_list);
  1563  
  1564          ret = soc_tplg_widget_ready(tplg, widget, w);
  1565          if (ret < 0)
  1566                  goto ready_err;

regards,
dan carpenter


More information about the Alsa-devel mailing list