root/sound/usb/validate.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. validate_uac1_header
  2. validate_mixer_unit
  3. validate_processing_unit
  4. validate_selector_unit
  5. validate_uac1_feature_unit
  6. validate_uac2_feature_unit
  7. validate_uac3_feature_unit
  8. validate_midi_out_jack
  9. validate_desc
  10. snd_usb_validate_audio_desc
  11. snd_usb_validate_midi_desc

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

/* [<][>][^][v][top][bottom][index][help] */