I think I understand why the USB exploit analyzed by Amnesty International uses both a virtual Extigy sound card and a FastTrackPro sound card.
https://securitylab.amnesty.org/latest/2025/02/cellebrite-zero-day-exploit-used-to-target-phone-of-serbian-student-activist/
It took me 6 weeks to notice: in the logs, the Extigy and the FastTrackPro sound cards are not two virtual devices.
They're one device with two interfaces.
Which explains why the device "morphs":
- it first returns Extigy as the USB VID/PID in its device descriptor
- the Extigy quirk causes Linux to re-fetch the device descriptor
- the Amnesty analysis points out that you can return a bigger bNumConfigurations in the new device descriptor to cause an out-of-bound read+free on disconnect
- but you can also return a different VID/PID - say, the FastTrackPro VID/PID
- and Linux will use that VID/PID to probe the next audio interface:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/card.c;l=773;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
Now you have a device with both a corrupted bNumConfigurations - and with VID/PID set to FastTrackPro, which now triggers FastTrackPro quirks.
The original writeup identifies that, like the Extigy, the FastTrackPro has quirks that are only run for that VID/PID.
Amnesty speculates that the attacker uses the FastTrackPro "to confirm that the memory corruption primitive CVE-2024-53197 is functional".
The writeup looks at the skip_setting quirk:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/quirks.c;l=1598;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
but there's also this boot quirk, which switches the device's configuration:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/quirks.c;l=1652;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
This calls to usb_set_configuration(dev, 2), which reads bNumConfigurations and looks for configuration #2.
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/drivers/usb/core/message.c;l=2007;drc=9f2a3933beeaeead53829d3a7be53770e41e7869
So if you wanted to confirm that your heap manipulation worked, in your fake `struct usb_host_config`, set 2 as your bConfigurationValue.
usb_set_configuration will read the corrupted bNumConfigurations and start reading `struct usb_host_config`s out of bounds.
If it finds configuration #2, it means your fake is located in the right place, right after the Extigy/FastTrackPro's own `struct usb_host_config`s.
And since the search doesn't dereference anything, you can't crash.