[alsa-devel] [bug report] ALSA: usb: add UAC3 BADD profiles support
Ruslan Bilovol
ruslan.bilovol at gmail.com
Wed May 16 13:36:54 CEST 2018
Hi Dan,
On Wed, May 16, 2018 at 2:32 PM, Dan Carpenter <dan.carpenter at oracle.com> wrote:
> [ Your patch didn't really introduce the bug, it just made it visible
> to static checkers. - dan ]
>
> Hello Ruslan Bilovol,
>
> The patch 17156f23e93c: "ALSA: usb: add UAC3 BADD profiles support"
> from May 4, 2018, leads to the following static checker warning:
>
> sound/usb/stream.c:984 snd_usb_get_audioformat_uac3()
> warn: possible memory leak of 'chmap'
>
> sound/usb/stream.c
> 864
> 865 chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
> 866 if (!chmap)
> 867 return ERR_PTR(-ENOMEM);
> 868
> 869 if (num_channels == 1) {
> 870 chmap->map[0] = SNDRV_CHMAP_MONO;
> 871 } else {
> 872 chmap->map[0] = SNDRV_CHMAP_FL;
> 873 chmap->map[1] = SNDRV_CHMAP_FR;
> 874 }
> 875
> 876 chmap->channels = num_channels;
> 877 clock = UAC3_BADD_CS_ID9;
> 878 goto found_clock;
> 879 }
> 880
> 881 as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
> 882 NULL, UAC_AS_GENERAL);
> 883 if (!as) {
> 884 dev_err(&dev->dev,
> 885 "%u:%d : UAC_AS_GENERAL descriptor not found\n",
> 886 iface_no, altno);
> 887 return NULL;
> 888 }
> 889
> 890 if (as->bLength < sizeof(*as)) {
> 891 dev_err(&dev->dev,
> 892 "%u:%d : invalid UAC_AS_GENERAL desc\n",
> 893 iface_no, altno);
> 894 return NULL;
> 895 }
> 896
> 897 cluster_id = le16_to_cpu(as->wClusterDescrID);
> 898 if (!cluster_id) {
> 899 dev_err(&dev->dev,
> 900 "%u:%d : no cluster descriptor\n",
> 901 iface_no, altno);
> 902 return NULL;
> 903 }
> 904
> 905 /*
> 906 * Get number of channels and channel map through
> 907 * High Capability Cluster Descriptor
> 908 *
> 909 * First step: get High Capability header and
> 910 * read size of Cluster Descriptor
> 911 */
> 912 err = snd_usb_ctl_msg(chip->dev,
> 913 usb_rcvctrlpipe(chip->dev, 0),
> 914 UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
> 915 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
> 916 cluster_id,
> 917 snd_usb_ctrl_intf(chip),
> 918 &hc_header, sizeof(hc_header));
> 919 if (err < 0)
> 920 return ERR_PTR(err);
> 921 else if (err != sizeof(hc_header)) {
> 922 dev_err(&dev->dev,
> 923 "%u:%d : can't get High Capability descriptor\n",
> 924 iface_no, altno);
> 925 return ERR_PTR(-EIO);
> 926 }
> 927
> 928 /*
> 929 * Second step: allocate needed amount of memory
> 930 * and request Cluster Descriptor
> 931 */
> 932 wLength = le16_to_cpu(hc_header.wLength);
> 933 cluster = kzalloc(wLength, GFP_KERNEL);
> 934 if (!cluster)
> 935 return ERR_PTR(-ENOMEM);
> 936 err = snd_usb_ctl_msg(chip->dev,
> 937 usb_rcvctrlpipe(chip->dev, 0),
> 938 UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
> 939 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
> 940 cluster_id,
> 941 snd_usb_ctrl_intf(chip),
> 942 cluster, wLength);
> 943 if (err < 0) {
> 944 kfree(cluster);
> 945 return ERR_PTR(err);
> 946 } else if (err != wLength) {
> 947 dev_err(&dev->dev,
> 948 "%u:%d : can't get Cluster Descriptor\n",
> 949 iface_no, altno);
> 950 kfree(cluster);
> 951 return ERR_PTR(-EIO);
> 952 }
> 953
> 954 num_channels = cluster->bNrChannels;
> 955 chmap = convert_chmap_v3(cluster);
> 956 kfree(cluster);
> 957
> 958 /*
> 959 * lookup the terminal associated to this interface
> 960 * to extract the clock
> 961 */
> 962 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
> 963 as->bTerminalLink);
> 964 if (input_term) {
> 965 clock = input_term->bCSourceID;
> 966 goto found_clock;
> 967 }
> 968
> 969 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
> 970 as->bTerminalLink);
> 971 if (output_term) {
> 972 clock = output_term->bCSourceID;
> 973 goto found_clock;
> 974 }
> 975
> 976 dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n",
> 977 iface_no, altno, as->bTerminalLink);
> 978 return NULL;
> 979
> 980 found_clock:
> 981 fp = audio_format_alloc_init(chip, alts, UAC_VERSION_3, iface_no,
> 982 altset_idx, altno, num_channels, clock);
> 983 if (!fp)
> 984 return ERR_PTR(-ENOMEM);
>
> We should free "chmap" before returning.
>
> 985
> 986 fp->chmap = chmap;
> 987
> 988 if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
> 989 fp->attributes = 0; /* No attributes */
> 990
> 991 fp->fmt_type = UAC_FORMAT_TYPE_I;
> 992 fp->formats = badd_formats;
> 993
> 994 fp->nr_rates = 0; /* SNDRV_PCM_RATE_CONTINUOUS */
> 995 fp->rate_min = UAC3_BADD_SAMPLING_RATE;
> 996 fp->rate_max = UAC3_BADD_SAMPLING_RATE;
> 997 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
> 998
> 999 } else {
> 1000 fp->attributes = parse_uac_endpoint_attributes(chip, alts,
> 1001 UAC_VERSION_3,
> 1002 iface_no);
> 1003 /* ok, let's parse further... */
> 1004 if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) {
> 1005 kfree(fp->rate_table);
> 1006 kfree(fp);
> 1007 return NULL;
>
> And here as well? I don't know.
Correct, this was not obvious before UAC3 refactoring, but now the
issue is clear.
I'll send a fix soon.
Thanks,
Ruslan
More information about the Alsa-devel
mailing list