VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46004

CVE-2026-46004

Description

In the Linux kernel, the following vulnerability has been resolved:

ALSA: caiaq: Handle probe errors properly

The probe procedure of setup_card() in caiaq driver doesn't treat the error cases gracefully, e.g. the error from snd_card_register() calls snd_card_free() but continues. This would lead to a UAF for the further calls like snd_usb_caiaq_control_init(), as Berk suggested in another patch in the link below.

However, the problem is not only that; in general, this function drops the all error handlings (as it's a void function) although its caller can propagate an error to snd_probe(), which eventually calls snd_card_free() as a proper error path. That said, we should treat each error case in setup_card(), and just return the error code promptly, which is then handled later as a fatal error in snd_probe().

This patch achieves it by changing the setup_card() to return an error code. Also, the superfluous snd_card_free() call is removed, too.

Note that card->private_free can be set still safely at returning an error. All called functions in card_free() have checks of the unassigned resources or NULL checks.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In the Linux kernel ALSA caiaq driver, improper error handling in probe can lead to use-after-free.

Vulnerability

In the Linux kernel ALSA caiaq driver, the probe procedure of setup_card() does not handle errors properly. After a failure like snd_card_register() error, it calls snd_card_free() but continues execution, leading to a use-after-free (UAF) when subsequent calls like snd_usb_caiaq_control_init() are made. Affected versions: before the fix commit e59ecd4ee3a4.

Exploitation

An attacker would need to trigger a probe error condition, such as by providing a malicious USB device that causes snd_card_register() to fail. The driver then continues to use freed memory, potentially leading to exploitation. No special privileges beyond physical USB access required.

Impact

Successful exploitation can lead to use-after-free, potentially allowing an attacker to cause a denial of service or escalate privileges. The exact impact depends on memory state.

Mitigation

The fix is in Linux kernel commit e59ecd4ee3a450db6cb4e4ecaa3efdd593f80056, which changes setup_card() to return an error code and removes the erroneous snd_card_free() call. Users should update to a kernel containing this commit.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

10
f537e3ad6960

ALSA: caiaq: Handle probe errors properly

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTakashi IwaiApr 14, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
28abd224db4a

ALSA: caiaq: Handle probe errors properly

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTakashi IwaiApr 14, 2026Fixed in 7.1-rc1via kernel-cna
2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
096dd8519cf2

ALSA: caiaq: Handle probe errors properly

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTakashi IwaiApr 14, 2026Fixed in 7.0.4via kernel-cna
2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
e59ecd4ee3a4

ALSA: caiaq: Handle probe errors properly

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTakashi IwaiApr 14, 2026Fixed in 6.18.27via kernel-cna
2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
6251e3e25633

ALSA: caiaq: Handle probe errors properly

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTakashi IwaiApr 14, 2026Fixed in 6.12.86via kernel-cna
2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
6251e3e25633

ALSA: caiaq: Handle probe errors properly

2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
096dd8519cf2

ALSA: caiaq: Handle probe errors properly

2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
28abd224db4a

ALSA: caiaq: Handle probe errors properly

2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
e59ecd4ee3a4

ALSA: caiaq: Handle probe errors properly

2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
f537e3ad6960

ALSA: caiaq: Handle probe errors properly

2 files changed · +48 20
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    
  • sound/usb/caiaq/device.c+24 10 modified
    diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
    index 51177ebfb8c627..8af0c04041ee3e 100644
    --- a/sound/usb/caiaq/device.c
    +++ b/sound/usb/caiaq/device.c
    @@ -290,7 +290,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
     					  tmp, sizeof(tmp));
     }
     
    -static void setup_card(struct snd_usb_caiaqdev *cdev)
    +static int setup_card(struct snd_usb_caiaqdev *cdev)
     {
     	int ret;
     	char val[4];
    @@ -325,8 +325,10 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     		snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
     
     		if (!wait_event_timeout(cdev->ep1_wait_queue,
    -					cdev->control_state[0] != 0xff, HZ))
    -			return;
    +					cdev->control_state[0] != 0xff, HZ)) {
    +			dev_err(dev, "Read timeout for control state\n");
    +			return -EINVAL;
    +		}
     
     		/* fix up some defaults */
     		if ((cdev->control_state[1] != 2) ||
    @@ -347,33 +349,43 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
     	    cdev->spec.num_digital_audio_out +
     	    cdev->spec.num_digital_audio_in > 0) {
     		ret = snd_usb_caiaq_audio_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     	if (cdev->spec.num_midi_in +
     	    cdev->spec.num_midi_out > 0) {
     		ret = snd_usb_caiaq_midi_init(cdev);
    -		if (ret < 0)
    +		if (ret < 0) {
     			dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
    +			return ret;
    +		}
     	}
     
     #ifdef CONFIG_SND_USB_CAIAQ_INPUT
     	ret = snd_usb_caiaq_input_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
    +		return ret;
    +	}
     #endif
     
     	/* finally, register the card and all its sub-instances */
     	ret = snd_card_register(cdev->chip.card);
     	if (ret < 0) {
     		dev_err(dev, "snd_card_register() returned %d\n", ret);
    -		snd_card_free(cdev->chip.card);
    +		return ret;
     	}
     
     	ret = snd_usb_caiaq_control_init(cdev);
    -	if (ret < 0)
    +	if (ret < 0) {
     		dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
    +		return ret;
    +	}
    +
    +	return 0;
     }
     
     static void card_free(struct snd_card *card)
    @@ -499,8 +511,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
     	scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
     		       cdev->vendor_name, cdev->product_name, usbpath);
     
    -	setup_card(cdev);
     	card->private_free = card_free;
    +	err = setup_card(cdev);
    +	if (err < 0)
    +		return err;
    +
     	return 0;
     
      err_kill_urb:
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing error handling in setup_card() allows use-after-free when probe failures are not propagated."

Attack vector

An attacker with physical USB access can plug a Native Instruments caiaq device that triggers a failure during probe — for example, a read timeout on the control state, or a failure in snd_card_register(). In the vulnerable code, setup_card() was a void function that either silently returned on error or, in the case of snd_card_register() failure, called snd_card_free() but then continued executing. This allowed subsequent calls like snd_usb_caiaq_control_init() to operate on a freed card structure, leading to a use-after-free condition [patch_id=2660518].

Affected code

The vulnerable code is in sound/usb/caiaq/device.c, specifically the setup_card() function and its caller init_card(). setup_card() was a void function that ignored or mishandled errors from snd_usb_caiaq_audio_init(), snd_usb_caiaq_midi_init(), snd_usb_caiaq_input_init(), snd_card_register(), and snd_usb_caiaq_control_init() [patch_id=2660518].

What the fix does

The patch changes setup_card() from void to int, making it return a negative error code on every failure path instead of silently returning or continuing after calling snd_card_free(). The superfluous snd_card_free() call inside the snd_card_register() error path is removed, because the caller init_card() now checks the return value of setup_card() and, on error, returns the error code to snd_probe(), which handles the proper teardown via snd_card_free(). The assignment of card->private_free is moved before the setup_card() call so it is always set, and the patch notes that card_free() safely handles unassigned resources [patch_id=2660518].

Preconditions

  • inputPhysical USB access to plug a Native Instruments caiaq device
  • inputThe device must trigger a probe failure (e.g., control state read timeout, snd_card_register failure)

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.