Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'sound-fix-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
"The main purpose of this pull request is a fix for a regression in the
recent PCM OSS emulation code that may lead to RCU stall. Since
syzkaller hits this too often, I send the pull request now with a
minimal collection. Possibly another pull request may follow before
RC1.

The other fixes here are for USB-audio class 2 and 3 to improve the
parser for the clock descriptors. These are rather cleanups but good
for security, too.

Last but not least, another included fix is the trivial one to remove
superfluous WARN_ON() that annoyed syzbot"

* tag 'sound-fix-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: pcm: Remove WARN_ON() at snd_pcm_hw_params() error
ALSA: pcm: Fix endless loop for XRUN recovery in OSS emulation
ALSA: usb-audio: Add sanity checks in UAC3 clock parsers
ALSA: usb-audio: More strict sanity checks for clock parsers
ALSA: usb-audio: Refactor clock finder helpers

+60 -79
+3 -2
sound/core/oss/pcm_oss.c
··· 1128 1128 } 1129 1129 1130 1130 /* call with params_lock held */ 1131 + /* NOTE: this always call PREPARE unconditionally no matter whether 1132 + * runtime->oss.prepare is set or not 1133 + */ 1131 1134 static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) 1132 1135 { 1133 1136 int err; 1134 1137 struct snd_pcm_runtime *runtime = substream->runtime; 1135 1138 1136 - if (!runtime->oss.prepare) 1137 - return 0; 1138 1139 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); 1139 1140 if (err < 0) { 1140 1141 pcm_dbg(substream->pcm,
+1 -1
sound/core/pcm_native.c
··· 617 617 changed = snd_pcm_hw_param_first(pcm, params, *v, NULL); 618 618 else 619 619 changed = snd_pcm_hw_param_last(pcm, params, *v, NULL); 620 - if (snd_BUG_ON(changed < 0)) 620 + if (changed < 0) 621 621 return changed; 622 622 if (changed == 0) 623 623 continue;
+56 -76
sound/usb/clock.c
··· 35 35 #include "clock.h" 36 36 #include "quirks.h" 37 37 38 - static struct uac_clock_source_descriptor * 39 - snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface, 40 - int clock_id) 38 + static void *find_uac_clock_desc(struct usb_host_interface *iface, int id, 39 + bool (*validator)(void *, int), u8 type) 41 40 { 42 - struct uac_clock_source_descriptor *cs = NULL; 41 + void *cs = NULL; 43 42 44 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 45 - ctrl_iface->extralen, 46 - cs, UAC2_CLOCK_SOURCE))) { 47 - if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) 43 + while ((cs = snd_usb_find_csint_desc(iface->extra, iface->extralen, 44 + cs, type))) { 45 + if (validator(cs, id)) 48 46 return cs; 49 47 } 50 48 51 49 return NULL; 52 50 } 53 51 54 - static struct uac3_clock_source_descriptor * 55 - snd_usb_find_clock_source_v3(struct usb_host_interface *ctrl_iface, 56 - int clock_id) 52 + static bool validate_clock_source_v2(void *p, int id) 57 53 { 58 - struct uac3_clock_source_descriptor *cs = NULL; 59 - 60 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 61 - ctrl_iface->extralen, 62 - cs, UAC3_CLOCK_SOURCE))) { 63 - if (cs->bClockID == clock_id) 64 - return cs; 65 - } 66 - 67 - return NULL; 54 + struct uac_clock_source_descriptor *cs = p; 55 + return cs->bLength == sizeof(*cs) && cs->bClockID == id; 68 56 } 69 57 70 - static struct uac_clock_selector_descriptor * 71 - snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface, 72 - int clock_id) 58 + static bool validate_clock_source_v3(void *p, int id) 73 59 { 74 - struct uac_clock_selector_descriptor *cs = NULL; 75 - 76 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 77 - ctrl_iface->extralen, 78 - cs, UAC2_CLOCK_SELECTOR))) { 79 - if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) { 80 - if (cs->bLength < 5 + cs->bNrInPins) 81 - return NULL; 82 - return cs; 83 - } 84 - } 85 - 86 - return NULL; 60 + struct uac3_clock_source_descriptor *cs = p; 61 + return cs->bLength == sizeof(*cs) && cs->bClockID == id; 87 62 } 88 63 89 - static struct uac3_clock_selector_descriptor * 90 - snd_usb_find_clock_selector_v3(struct usb_host_interface *ctrl_iface, 91 - int clock_id) 64 + static bool validate_clock_selector_v2(void *p, int id) 92 65 { 93 - struct uac3_clock_selector_descriptor *cs = NULL; 94 - 95 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 96 - ctrl_iface->extralen, 97 - cs, UAC3_CLOCK_SELECTOR))) { 98 - if (cs->bClockID == clock_id) 99 - return cs; 100 - } 101 - 102 - return NULL; 66 + struct uac_clock_selector_descriptor *cs = p; 67 + return cs->bLength >= sizeof(*cs) && cs->bClockID == id && 68 + cs->bLength == 7 + cs->bNrInPins; 103 69 } 104 70 105 - static struct uac_clock_multiplier_descriptor * 106 - snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface, 107 - int clock_id) 71 + static bool validate_clock_selector_v3(void *p, int id) 108 72 { 109 - struct uac_clock_multiplier_descriptor *cs = NULL; 110 - 111 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 112 - ctrl_iface->extralen, 113 - cs, UAC2_CLOCK_MULTIPLIER))) { 114 - if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) 115 - return cs; 116 - } 117 - 118 - return NULL; 73 + struct uac3_clock_selector_descriptor *cs = p; 74 + return cs->bLength >= sizeof(*cs) && cs->bClockID == id && 75 + cs->bLength == 11 + cs->bNrInPins; 119 76 } 120 77 121 - static struct uac3_clock_multiplier_descriptor * 122 - snd_usb_find_clock_multiplier_v3(struct usb_host_interface *ctrl_iface, 123 - int clock_id) 78 + static bool validate_clock_multiplier_v2(void *p, int id) 124 79 { 125 - struct uac3_clock_multiplier_descriptor *cs = NULL; 126 - 127 - while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, 128 - ctrl_iface->extralen, 129 - cs, UAC3_CLOCK_MULTIPLIER))) { 130 - if (cs->bClockID == clock_id) 131 - return cs; 132 - } 133 - 134 - return NULL; 80 + struct uac_clock_multiplier_descriptor *cs = p; 81 + return cs->bLength == sizeof(*cs) && cs->bClockID == id; 135 82 } 83 + 84 + static bool validate_clock_multiplier_v3(void *p, int id) 85 + { 86 + struct uac3_clock_multiplier_descriptor *cs = p; 87 + return cs->bLength == sizeof(*cs) && cs->bClockID == id; 88 + } 89 + 90 + #define DEFINE_FIND_HELPER(name, obj, validator, type) \ 91 + static obj *name(struct usb_host_interface *iface, int id) \ 92 + { \ 93 + return find_uac_clock_desc(iface, id, validator, type); \ 94 + } 95 + 96 + DEFINE_FIND_HELPER(snd_usb_find_clock_source, 97 + struct uac_clock_source_descriptor, 98 + validate_clock_source_v2, UAC2_CLOCK_SOURCE); 99 + DEFINE_FIND_HELPER(snd_usb_find_clock_source_v3, 100 + struct uac3_clock_source_descriptor, 101 + validate_clock_source_v3, UAC3_CLOCK_SOURCE); 102 + 103 + DEFINE_FIND_HELPER(snd_usb_find_clock_selector, 104 + struct uac_clock_selector_descriptor, 105 + validate_clock_selector_v2, UAC2_CLOCK_SELECTOR); 106 + DEFINE_FIND_HELPER(snd_usb_find_clock_selector_v3, 107 + struct uac3_clock_selector_descriptor, 108 + validate_clock_selector_v3, UAC3_CLOCK_SELECTOR); 109 + 110 + DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier, 111 + struct uac_clock_multiplier_descriptor, 112 + validate_clock_multiplier_v2, UAC2_CLOCK_MULTIPLIER); 113 + DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier_v3, 114 + struct uac3_clock_multiplier_descriptor, 115 + validate_clock_multiplier_v3, UAC3_CLOCK_MULTIPLIER); 136 116 137 117 static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id) 138 118 {