1 // SPDX-License-Identifier: GPL-2.0-or-later 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // 2 // 3 // Validation of USB-audio class descriptors 3 // Validation of USB-audio class descriptors 4 // 4 // 5 5 6 #include <linux/init.h> 6 #include <linux/init.h> 7 #include <linux/usb.h> 7 #include <linux/usb.h> 8 #include <linux/usb/audio.h> 8 #include <linux/usb/audio.h> 9 #include <linux/usb/audio-v2.h> 9 #include <linux/usb/audio-v2.h> 10 #include <linux/usb/audio-v3.h> 10 #include <linux/usb/audio-v3.h> 11 #include <linux/usb/midi.h> 11 #include <linux/usb/midi.h> 12 #include "usbaudio.h" 12 #include "usbaudio.h" 13 #include "helper.h" 13 #include "helper.h" 14 14 15 struct usb_desc_validator { 15 struct usb_desc_validator { 16 unsigned char protocol; 16 unsigned char protocol; 17 unsigned char type; 17 unsigned char type; 18 bool (*func)(const void *p, const stru 18 bool (*func)(const void *p, const struct usb_desc_validator *v); 19 size_t size; 19 size_t size; 20 }; 20 }; 21 21 22 #define UAC_VERSION_ALL (unsigned char 22 #define UAC_VERSION_ALL (unsigned char)(-1) 23 23 24 /* UAC1 only */ 24 /* UAC1 only */ 25 static bool validate_uac1_header(const void *p 25 static bool validate_uac1_header(const void *p, 26 const struct 26 const struct usb_desc_validator *v) 27 { 27 { 28 const struct uac1_ac_header_descriptor 28 const struct uac1_ac_header_descriptor *d = p; 29 29 30 return d->bLength >= sizeof(*d) && 30 return d->bLength >= sizeof(*d) && 31 d->bLength >= sizeof(*d) + d-> 31 d->bLength >= sizeof(*d) + d->bInCollection; 32 } 32 } 33 33 34 /* for mixer unit; covering all UACs */ 34 /* for mixer unit; covering all UACs */ 35 static bool validate_mixer_unit(const void *p, 35 static bool validate_mixer_unit(const void *p, 36 const struct u 36 const struct usb_desc_validator *v) 37 { 37 { 38 const struct uac_mixer_unit_descriptor 38 const struct uac_mixer_unit_descriptor *d = p; 39 size_t len; 39 size_t len; 40 40 41 if (d->bLength < sizeof(*d) || !d->bNr 41 if (d->bLength < sizeof(*d) || !d->bNrInPins) 42 return false; 42 return false; 43 len = sizeof(*d) + d->bNrInPins; 43 len = sizeof(*d) + d->bNrInPins; 44 /* We can't determine the bitmap size 44 /* We can't determine the bitmap size only from this unit descriptor, 45 * so just check with the remaining le 45 * so just check with the remaining length. 46 * The actual bitmap is checked at mix 46 * The actual bitmap is checked at mixer unit parser. 47 */ 47 */ 48 switch (v->protocol) { 48 switch (v->protocol) { 49 case UAC_VERSION_1: 49 case UAC_VERSION_1: 50 default: 50 default: 51 len += 2 + 1; /* wChannelConfi 51 len += 2 + 1; /* wChannelConfig, iChannelNames */ 52 /* bmControls[n*m] */ 52 /* bmControls[n*m] */ 53 len += 1; /* iMixer */ 53 len += 1; /* iMixer */ 54 break; 54 break; 55 case UAC_VERSION_2: 55 case UAC_VERSION_2: 56 len += 4 + 1; /* bmChannelConf 56 len += 4 + 1; /* bmChannelConfig, iChannelNames */ 57 /* bmMixerControls[n*m] */ 57 /* bmMixerControls[n*m] */ 58 len += 1 + 1; /* bmControls, i 58 len += 1 + 1; /* bmControls, iMixer */ 59 break; 59 break; 60 case UAC_VERSION_3: 60 case UAC_VERSION_3: 61 len += 2; /* wClusterDescrID * 61 len += 2; /* wClusterDescrID */ 62 /* bmMixerControls[n*m] */ 62 /* bmMixerControls[n*m] */ 63 break; 63 break; 64 } 64 } 65 return d->bLength >= len; 65 return d->bLength >= len; 66 } 66 } 67 67 68 /* both for processing and extension units; co 68 /* both for processing and extension units; covering all UACs */ 69 static bool validate_processing_unit(const voi 69 static bool validate_processing_unit(const void *p, 70 const str 70 const struct usb_desc_validator *v) 71 { 71 { 72 const struct uac_processing_unit_descr 72 const struct uac_processing_unit_descriptor *d = p; 73 const unsigned char *hdr = p; 73 const unsigned char *hdr = p; 74 size_t len, m; 74 size_t len, m; 75 75 76 if (d->bLength < sizeof(*d)) 76 if (d->bLength < sizeof(*d)) 77 return false; 77 return false; 78 len = sizeof(*d) + d->bNrInPins; 78 len = sizeof(*d) + d->bNrInPins; 79 if (d->bLength < len) 79 if (d->bLength < len) 80 return false; 80 return false; 81 switch (v->protocol) { 81 switch (v->protocol) { 82 case UAC_VERSION_1: 82 case UAC_VERSION_1: 83 default: 83 default: 84 /* bNrChannels, wChannelConfig 84 /* bNrChannels, wChannelConfig, iChannelNames */ 85 len += 1 + 2 + 1; 85 len += 1 + 2 + 1; 86 if (d->bLength < len + 1) /* b 86 if (d->bLength < len + 1) /* bControlSize */ 87 return false; 87 return false; 88 m = hdr[len]; 88 m = hdr[len]; 89 len += 1 + m + 1; /* bControlS 89 len += 1 + m + 1; /* bControlSize, bmControls, iProcessing */ 90 break; 90 break; 91 case UAC_VERSION_2: 91 case UAC_VERSION_2: 92 /* bNrChannels, bmChannelConfi 92 /* bNrChannels, bmChannelConfig, iChannelNames */ 93 len += 1 + 4 + 1; 93 len += 1 + 4 + 1; 94 if (v->type == UAC2_PROCESSING 94 if (v->type == UAC2_PROCESSING_UNIT_V2) 95 len += 2; /* bmControl 95 len += 2; /* bmControls -- 2 bytes for PU */ 96 else 96 else 97 len += 1; /* bmControl 97 len += 1; /* bmControls -- 1 byte for EU */ 98 len += 1; /* iProcessing */ 98 len += 1; /* iProcessing */ 99 break; 99 break; 100 case UAC_VERSION_3: 100 case UAC_VERSION_3: 101 /* wProcessingDescrStr, bmCont 101 /* wProcessingDescrStr, bmControls */ 102 len += 2 + 4; 102 len += 2 + 4; 103 break; 103 break; 104 } 104 } 105 if (d->bLength < len) 105 if (d->bLength < len) 106 return false; 106 return false; 107 107 108 switch (v->protocol) { 108 switch (v->protocol) { 109 case UAC_VERSION_1: 109 case UAC_VERSION_1: 110 default: 110 default: 111 if (v->type == UAC1_EXTENSION_ 111 if (v->type == UAC1_EXTENSION_UNIT) 112 return true; /* OK */ 112 return true; /* OK */ 113 switch (le16_to_cpu(d->wProces 113 switch (le16_to_cpu(d->wProcessType)) { 114 case UAC_PROCESS_UP_DOWNMIX: 114 case UAC_PROCESS_UP_DOWNMIX: 115 case UAC_PROCESS_DOLBY_PROLOGI 115 case UAC_PROCESS_DOLBY_PROLOGIC: 116 if (d->bLength < len + 116 if (d->bLength < len + 1) /* bNrModes */ 117 return false; 117 return false; 118 m = hdr[len]; 118 m = hdr[len]; 119 len += 1 + m * 2; /* b 119 len += 1 + m * 2; /* bNrModes, waModes(n) */ 120 break; 120 break; 121 default: 121 default: 122 break; 122 break; 123 } 123 } 124 break; 124 break; 125 case UAC_VERSION_2: 125 case UAC_VERSION_2: 126 if (v->type == UAC2_EXTENSION_ 126 if (v->type == UAC2_EXTENSION_UNIT_V2) 127 return true; /* OK */ 127 return true; /* OK */ 128 switch (le16_to_cpu(d->wProces 128 switch (le16_to_cpu(d->wProcessType)) { 129 case UAC2_PROCESS_UP_DOWNMIX: 129 case UAC2_PROCESS_UP_DOWNMIX: 130 case UAC2_PROCESS_DOLBY_PROLOC 130 case UAC2_PROCESS_DOLBY_PROLOCIC: /* SiC! */ 131 if (d->bLength < len + 131 if (d->bLength < len + 1) /* bNrModes */ 132 return false; 132 return false; 133 m = hdr[len]; 133 m = hdr[len]; 134 len += 1 + m * 4; /* b 134 len += 1 + m * 4; /* bNrModes, daModes(n) */ 135 break; 135 break; 136 default: 136 default: 137 break; 137 break; 138 } 138 } 139 break; 139 break; 140 case UAC_VERSION_3: 140 case UAC_VERSION_3: 141 if (v->type == UAC3_EXTENSION_ 141 if (v->type == UAC3_EXTENSION_UNIT) { 142 len += 2; /* wClusterD 142 len += 2; /* wClusterDescrID */ 143 break; 143 break; 144 } 144 } 145 switch (le16_to_cpu(d->wProces 145 switch (le16_to_cpu(d->wProcessType)) { 146 case UAC3_PROCESS_UP_DOWNMIX: 146 case UAC3_PROCESS_UP_DOWNMIX: 147 if (d->bLength < len + 147 if (d->bLength < len + 1) /* bNrModes */ 148 return false; 148 return false; 149 m = hdr[len]; 149 m = hdr[len]; 150 len += 1 + m * 2; /* b 150 len += 1 + m * 2; /* bNrModes, waClusterDescrID(n) */ 151 break; 151 break; 152 case UAC3_PROCESS_MULTI_FUNCTI 152 case UAC3_PROCESS_MULTI_FUNCTION: 153 len += 2 + 4; /* wClus 153 len += 2 + 4; /* wClusterDescrID, bmAlgorighms */ 154 break; 154 break; 155 default: 155 default: 156 break; 156 break; 157 } 157 } 158 break; 158 break; 159 } 159 } 160 if (d->bLength < len) 160 if (d->bLength < len) 161 return false; 161 return false; 162 162 163 return true; 163 return true; 164 } 164 } 165 165 166 /* both for selector and clock selector units; 166 /* both for selector and clock selector units; covering all UACs */ 167 static bool validate_selector_unit(const void 167 static bool validate_selector_unit(const void *p, 168 const struc 168 const struct usb_desc_validator *v) 169 { 169 { 170 const struct uac_selector_unit_descrip 170 const struct uac_selector_unit_descriptor *d = p; 171 size_t len; 171 size_t len; 172 172 173 if (d->bLength < sizeof(*d)) 173 if (d->bLength < sizeof(*d)) 174 return false; 174 return false; 175 len = sizeof(*d) + d->bNrInPins; 175 len = sizeof(*d) + d->bNrInPins; 176 switch (v->protocol) { 176 switch (v->protocol) { 177 case UAC_VERSION_1: 177 case UAC_VERSION_1: 178 default: 178 default: 179 len += 1; /* iSelector */ 179 len += 1; /* iSelector */ 180 break; 180 break; 181 case UAC_VERSION_2: 181 case UAC_VERSION_2: 182 len += 1 + 1; /* bmControls, i 182 len += 1 + 1; /* bmControls, iSelector */ 183 break; 183 break; 184 case UAC_VERSION_3: 184 case UAC_VERSION_3: 185 len += 4 + 2; /* bmControls, w 185 len += 4 + 2; /* bmControls, wSelectorDescrStr */ 186 break; 186 break; 187 } 187 } 188 return d->bLength >= len; 188 return d->bLength >= len; 189 } 189 } 190 190 191 static bool validate_uac1_feature_unit(const v 191 static bool validate_uac1_feature_unit(const void *p, 192 const s 192 const struct usb_desc_validator *v) 193 { 193 { 194 const struct uac_feature_unit_descript 194 const struct uac_feature_unit_descriptor *d = p; 195 195 196 if (d->bLength < sizeof(*d) || !d->bCo 196 if (d->bLength < sizeof(*d) || !d->bControlSize) 197 return false; 197 return false; 198 /* at least bmaControls(0) for master 198 /* at least bmaControls(0) for master channel + iFeature */ 199 return d->bLength >= sizeof(*d) + d->b 199 return d->bLength >= sizeof(*d) + d->bControlSize + 1; 200 } 200 } 201 201 202 static bool validate_uac2_feature_unit(const v 202 static bool validate_uac2_feature_unit(const void *p, 203 const s 203 const struct usb_desc_validator *v) 204 { 204 { 205 const struct uac2_feature_unit_descrip 205 const struct uac2_feature_unit_descriptor *d = p; 206 206 207 if (d->bLength < sizeof(*d)) 207 if (d->bLength < sizeof(*d)) 208 return false; 208 return false; 209 /* at least bmaControls(0) for master 209 /* at least bmaControls(0) for master channel + iFeature */ 210 return d->bLength >= sizeof(*d) + 4 + 210 return d->bLength >= sizeof(*d) + 4 + 1; 211 } 211 } 212 212 213 static bool validate_uac3_feature_unit(const v 213 static bool validate_uac3_feature_unit(const void *p, 214 const s 214 const struct usb_desc_validator *v) 215 { 215 { 216 const struct uac3_feature_unit_descrip 216 const struct uac3_feature_unit_descriptor *d = p; 217 217 218 if (d->bLength < sizeof(*d)) 218 if (d->bLength < sizeof(*d)) 219 return false; 219 return false; 220 /* at least bmaControls(0) for master 220 /* at least bmaControls(0) for master channel + wFeatureDescrStr */ 221 return d->bLength >= sizeof(*d) + 4 + 221 return d->bLength >= sizeof(*d) + 4 + 2; 222 } 222 } 223 223 224 static bool validate_midi_out_jack(const void 224 static bool validate_midi_out_jack(const void *p, 225 const struc 225 const struct usb_desc_validator *v) 226 { 226 { 227 const struct usb_midi_out_jack_descrip 227 const struct usb_midi_out_jack_descriptor *d = p; 228 228 229 return d->bLength >= sizeof(*d) && 229 return d->bLength >= sizeof(*d) && 230 d->bLength >= sizeof(*d) + d-> 230 d->bLength >= sizeof(*d) + d->bNrInputPins * 2; 231 } 231 } 232 232 233 #define FIXED(p, t, s) { .protocol = (p), .typ 233 #define FIXED(p, t, s) { .protocol = (p), .type = (t), .size = sizeof(s) } 234 #define FUNC(p, t, f) { .protocol = (p), .type 234 #define FUNC(p, t, f) { .protocol = (p), .type = (t), .func = (f) } 235 235 236 static const struct usb_desc_validator audio_v 236 static const struct usb_desc_validator audio_validators[] = { 237 /* UAC1 */ 237 /* UAC1 */ 238 FUNC(UAC_VERSION_1, UAC_HEADER, valida 238 FUNC(UAC_VERSION_1, UAC_HEADER, validate_uac1_header), 239 FIXED(UAC_VERSION_1, UAC_INPUT_TERMINA 239 FIXED(UAC_VERSION_1, UAC_INPUT_TERMINAL, 240 struct uac_input_terminal_descri 240 struct uac_input_terminal_descriptor), 241 FIXED(UAC_VERSION_1, UAC_OUTPUT_TERMIN 241 FIXED(UAC_VERSION_1, UAC_OUTPUT_TERMINAL, 242 struct uac1_output_terminal_desc 242 struct uac1_output_terminal_descriptor), 243 FUNC(UAC_VERSION_1, UAC_MIXER_UNIT, va 243 FUNC(UAC_VERSION_1, UAC_MIXER_UNIT, validate_mixer_unit), 244 FUNC(UAC_VERSION_1, UAC_SELECTOR_UNIT, 244 FUNC(UAC_VERSION_1, UAC_SELECTOR_UNIT, validate_selector_unit), 245 FUNC(UAC_VERSION_1, UAC_FEATURE_UNIT, 245 FUNC(UAC_VERSION_1, UAC_FEATURE_UNIT, validate_uac1_feature_unit), 246 FUNC(UAC_VERSION_1, UAC1_PROCESSING_UN 246 FUNC(UAC_VERSION_1, UAC1_PROCESSING_UNIT, validate_processing_unit), 247 FUNC(UAC_VERSION_1, UAC1_EXTENSION_UNI 247 FUNC(UAC_VERSION_1, UAC1_EXTENSION_UNIT, validate_processing_unit), 248 248 249 /* UAC2 */ 249 /* UAC2 */ 250 FIXED(UAC_VERSION_2, UAC_HEADER, struc 250 FIXED(UAC_VERSION_2, UAC_HEADER, struct uac2_ac_header_descriptor), 251 FIXED(UAC_VERSION_2, UAC_INPUT_TERMINA 251 FIXED(UAC_VERSION_2, UAC_INPUT_TERMINAL, 252 struct uac2_input_terminal_descr 252 struct uac2_input_terminal_descriptor), 253 FIXED(UAC_VERSION_2, UAC_OUTPUT_TERMIN 253 FIXED(UAC_VERSION_2, UAC_OUTPUT_TERMINAL, 254 struct uac2_output_terminal_desc 254 struct uac2_output_terminal_descriptor), 255 FUNC(UAC_VERSION_2, UAC_MIXER_UNIT, va 255 FUNC(UAC_VERSION_2, UAC_MIXER_UNIT, validate_mixer_unit), 256 FUNC(UAC_VERSION_2, UAC_SELECTOR_UNIT, 256 FUNC(UAC_VERSION_2, UAC_SELECTOR_UNIT, validate_selector_unit), 257 FUNC(UAC_VERSION_2, UAC_FEATURE_UNIT, 257 FUNC(UAC_VERSION_2, UAC_FEATURE_UNIT, validate_uac2_feature_unit), 258 /* UAC_VERSION_2, UAC2_EFFECT_UNIT: no 258 /* UAC_VERSION_2, UAC2_EFFECT_UNIT: not implemented yet */ 259 FUNC(UAC_VERSION_2, UAC2_PROCESSING_UN 259 FUNC(UAC_VERSION_2, UAC2_PROCESSING_UNIT_V2, validate_processing_unit), 260 FUNC(UAC_VERSION_2, UAC2_EXTENSION_UNI 260 FUNC(UAC_VERSION_2, UAC2_EXTENSION_UNIT_V2, validate_processing_unit), 261 FIXED(UAC_VERSION_2, UAC2_CLOCK_SOURCE 261 FIXED(UAC_VERSION_2, UAC2_CLOCK_SOURCE, 262 struct uac_clock_source_descript 262 struct uac_clock_source_descriptor), 263 FUNC(UAC_VERSION_2, UAC2_CLOCK_SELECTO 263 FUNC(UAC_VERSION_2, UAC2_CLOCK_SELECTOR, validate_selector_unit), 264 FIXED(UAC_VERSION_2, UAC2_CLOCK_MULTIP 264 FIXED(UAC_VERSION_2, UAC2_CLOCK_MULTIPLIER, 265 struct uac_clock_multiplier_desc 265 struct uac_clock_multiplier_descriptor), 266 /* UAC_VERSION_2, UAC2_SAMPLE_RATE_CON 266 /* UAC_VERSION_2, UAC2_SAMPLE_RATE_CONVERTER: not implemented yet */ 267 267 268 /* UAC3 */ 268 /* UAC3 */ 269 FIXED(UAC_VERSION_2, UAC_HEADER, struc 269 FIXED(UAC_VERSION_2, UAC_HEADER, struct uac3_ac_header_descriptor), 270 FIXED(UAC_VERSION_3, UAC_INPUT_TERMINA 270 FIXED(UAC_VERSION_3, UAC_INPUT_TERMINAL, 271 struct uac3_input_terminal_descr 271 struct uac3_input_terminal_descriptor), 272 FIXED(UAC_VERSION_3, UAC_OUTPUT_TERMIN 272 FIXED(UAC_VERSION_3, UAC_OUTPUT_TERMINAL, 273 struct uac3_output_terminal_desc 273 struct uac3_output_terminal_descriptor), 274 /* UAC_VERSION_3, UAC3_EXTENDED_TERMIN 274 /* UAC_VERSION_3, UAC3_EXTENDED_TERMINAL: not implemented yet */ 275 FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, v 275 FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, validate_mixer_unit), 276 FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT 276 FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT, validate_selector_unit), 277 FUNC(UAC_VERSION_3, UAC_FEATURE_UNIT, 277 FUNC(UAC_VERSION_3, UAC_FEATURE_UNIT, validate_uac3_feature_unit), 278 /* UAC_VERSION_3, UAC3_EFFECT_UNIT: n 278 /* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */ 279 FUNC(UAC_VERSION_3, UAC3_PROCESSING_UN 279 FUNC(UAC_VERSION_3, UAC3_PROCESSING_UNIT, validate_processing_unit), 280 FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNI 280 FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit), 281 FIXED(UAC_VERSION_3, UAC3_CLOCK_SOURCE 281 FIXED(UAC_VERSION_3, UAC3_CLOCK_SOURCE, 282 struct uac3_clock_source_descrip 282 struct uac3_clock_source_descriptor), 283 FUNC(UAC_VERSION_3, UAC3_CLOCK_SELECTO 283 FUNC(UAC_VERSION_3, UAC3_CLOCK_SELECTOR, validate_selector_unit), 284 FIXED(UAC_VERSION_3, UAC3_CLOCK_MULTIP 284 FIXED(UAC_VERSION_3, UAC3_CLOCK_MULTIPLIER, 285 struct uac3_clock_multiplier_des 285 struct uac3_clock_multiplier_descriptor), 286 /* UAC_VERSION_3, UAC3_SAMPLE_RATE_CON 286 /* UAC_VERSION_3, UAC3_SAMPLE_RATE_CONVERTER: not implemented yet */ 287 /* UAC_VERSION_3, UAC3_CONNECTORS: not 287 /* UAC_VERSION_3, UAC3_CONNECTORS: not implemented yet */ 288 { } /* terminator */ 288 { } /* terminator */ 289 }; 289 }; 290 290 291 static const struct usb_desc_validator midi_va 291 static const struct usb_desc_validator midi_validators[] = { 292 FIXED(UAC_VERSION_ALL, USB_MS_HEADER, 292 FIXED(UAC_VERSION_ALL, USB_MS_HEADER, 293 struct usb_ms_header_descriptor) 293 struct usb_ms_header_descriptor), 294 FIXED(UAC_VERSION_ALL, USB_MS_MIDI_IN_ 294 FIXED(UAC_VERSION_ALL, USB_MS_MIDI_IN_JACK, 295 struct usb_midi_in_jack_descript 295 struct usb_midi_in_jack_descriptor), 296 FUNC(UAC_VERSION_ALL, USB_MS_MIDI_OUT_ 296 FUNC(UAC_VERSION_ALL, USB_MS_MIDI_OUT_JACK, 297 validate_midi_out_jack), 297 validate_midi_out_jack), 298 { } /* terminator */ 298 { } /* terminator */ 299 }; 299 }; 300 300 301 301 302 /* Validate the given unit descriptor, return 302 /* Validate the given unit descriptor, return true if it's OK */ 303 static bool validate_desc(unsigned char *hdr, 303 static bool validate_desc(unsigned char *hdr, int protocol, 304 const struct usb_des 304 const struct usb_desc_validator *v) 305 { 305 { 306 if (hdr[1] != USB_DT_CS_INTERFACE) 306 if (hdr[1] != USB_DT_CS_INTERFACE) 307 return true; /* don't care */ 307 return true; /* don't care */ 308 308 309 for (; v->type; v++) { 309 for (; v->type; v++) { 310 if (v->type == hdr[2] && 310 if (v->type == hdr[2] && 311 (v->protocol == UAC_VERSIO 311 (v->protocol == UAC_VERSION_ALL || 312 v->protocol == protocol)) 312 v->protocol == protocol)) { 313 if (v->func) 313 if (v->func) 314 return v->func 314 return v->func(hdr, v); 315 /* check for the fixed 315 /* check for the fixed size */ 316 return hdr[0] >= v->si 316 return hdr[0] >= v->size; 317 } 317 } 318 } 318 } 319 319 320 return true; /* not matching, skip val 320 return true; /* not matching, skip validation */ 321 } 321 } 322 322 323 bool snd_usb_validate_audio_desc(void *p, int 323 bool snd_usb_validate_audio_desc(void *p, int protocol) 324 { 324 { 325 unsigned char *c = p; !! 325 return validate_desc(p, protocol, audio_validators); 326 bool valid; << 327 << 328 valid = validate_desc(p, protocol, aud << 329 if (!valid && snd_usb_skip_validation) << 330 print_hex_dump(KERN_ERR, "USB- << 331 DUMP_PREFIX_NON << 332 valid = true; << 333 } << 334 return valid; << 335 } 326 } 336 327 337 bool snd_usb_validate_midi_desc(void *p) 328 bool snd_usb_validate_midi_desc(void *p) 338 { 329 { 339 unsigned char *c = p; !! 330 return validate_desc(p, UAC_VERSION_1, midi_validators); 340 bool valid; << 341 << 342 valid = validate_desc(p, UAC_VERSION_1 << 343 if (!valid && snd_usb_skip_validation) << 344 print_hex_dump(KERN_ERR, "USB- << 345 DUMP_PREFIX_NON << 346 valid = true; << 347 } << 348 return valid; << 349 } 331 } >> 332 350 333
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.