[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