~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/usb/validate.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/usb/validate.c (Version linux-6.12-rc7) and /sound/usb/validate.c (Version policy-sample)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  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 stru    
 19         size_t size;                              
 20 };                                                
 21                                                   
 22 #define UAC_VERSION_ALL         (unsigned char    
 23                                                   
 24 /* UAC1 only */                                   
 25 static bool validate_uac1_header(const void *p    
 26                                  const struct     
 27 {                                                 
 28         const struct uac1_ac_header_descriptor    
 29                                                   
 30         return d->bLength >= sizeof(*d) &&        
 31                 d->bLength >= sizeof(*d) + d->    
 32 }                                                 
 33                                                   
 34 /* for mixer unit; covering all UACs */           
 35 static bool validate_mixer_unit(const void *p,    
 36                                 const struct u    
 37 {                                                 
 38         const struct uac_mixer_unit_descriptor    
 39         size_t len;                               
 40                                                   
 41         if (d->bLength < sizeof(*d) || !d->bNr    
 42                 return false;                     
 43         len = sizeof(*d) + d->bNrInPins;          
 44         /* We can't determine the bitmap size     
 45          * so just check with the remaining le    
 46          * The actual bitmap is checked at mix    
 47          */                                       
 48         switch (v->protocol) {                    
 49         case UAC_VERSION_1:                       
 50         default:                                  
 51                 len += 2 + 1; /* wChannelConfi    
 52                 /* bmControls[n*m] */             
 53                 len += 1; /* iMixer */            
 54                 break;                            
 55         case UAC_VERSION_2:                       
 56                 len += 4 + 1; /* bmChannelConf    
 57                 /* bmMixerControls[n*m] */        
 58                 len += 1 + 1; /* bmControls, i    
 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; co    
 69 static bool validate_processing_unit(const voi    
 70                                      const str    
 71 {                                                 
 72         const struct uac_processing_unit_descr    
 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    
 85                 len += 1 + 2 + 1;                 
 86                 if (d->bLength < len + 1) /* b    
 87                         return false;             
 88                 m = hdr[len];                     
 89                 len += 1 + m + 1; /* bControlS    
 90                 break;                            
 91         case UAC_VERSION_2:                       
 92                 /* bNrChannels, bmChannelConfi    
 93                 len += 1 + 4 + 1;                 
 94                 if (v->type == UAC2_PROCESSING    
 95                         len += 2; /* bmControl    
 96                 else                              
 97                         len += 1; /* bmControl    
 98                 len += 1; /* iProcessing */       
 99                 break;                            
100         case UAC_VERSION_3:                       
101                 /* wProcessingDescrStr, bmCont    
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_    
112                         return true; /* OK */     
113                 switch (le16_to_cpu(d->wProces    
114                 case UAC_PROCESS_UP_DOWNMIX:      
115                 case UAC_PROCESS_DOLBY_PROLOGI    
116                         if (d->bLength < len +    
117                                 return false;     
118                         m = hdr[len];             
119                         len += 1 + m * 2; /* b    
120                         break;                    
121                 default:                          
122                         break;                    
123                 }                                 
124                 break;                            
125         case UAC_VERSION_2:                       
126                 if (v->type == UAC2_EXTENSION_    
127                         return true; /* OK */     
128                 switch (le16_to_cpu(d->wProces    
129                 case UAC2_PROCESS_UP_DOWNMIX:     
130                 case UAC2_PROCESS_DOLBY_PROLOC    
131                         if (d->bLength < len +    
132                                 return false;     
133                         m = hdr[len];             
134                         len += 1 + m * 4; /* b    
135                         break;                    
136                 default:                          
137                         break;                    
138                 }                                 
139                 break;                            
140         case UAC_VERSION_3:                       
141                 if (v->type == UAC3_EXTENSION_    
142                         len += 2; /* wClusterD    
143                         break;                    
144                 }                                 
145                 switch (le16_to_cpu(d->wProces    
146                 case UAC3_PROCESS_UP_DOWNMIX:     
147                         if (d->bLength < len +    
148                                 return false;     
149                         m = hdr[len];             
150                         len += 1 + m * 2; /* b    
151                         break;                    
152                 case UAC3_PROCESS_MULTI_FUNCTI    
153                         len += 2 + 4; /* wClus    
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;    
167 static bool validate_selector_unit(const void     
168                                    const struc    
169 {                                                 
170         const struct uac_selector_unit_descrip    
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, i    
183                 break;                            
184         case UAC_VERSION_3:                       
185                 len += 4 + 2; /* bmControls, w    
186                 break;                            
187         }                                         
188         return d->bLength >= len;                 
189 }                                                 
190                                                   
191 static bool validate_uac1_feature_unit(const v    
192                                        const s    
193 {                                                 
194         const struct uac_feature_unit_descript    
195                                                   
196         if (d->bLength < sizeof(*d) || !d->bCo    
197                 return false;                     
198         /* at least bmaControls(0) for master     
199         return d->bLength >= sizeof(*d) + d->b    
200 }                                                 
201                                                   
202 static bool validate_uac2_feature_unit(const v    
203                                        const s    
204 {                                                 
205         const struct uac2_feature_unit_descrip    
206                                                   
207         if (d->bLength < sizeof(*d))              
208                 return false;                     
209         /* at least bmaControls(0) for master     
210         return d->bLength >= sizeof(*d) + 4 +     
211 }                                                 
212                                                   
213 static bool validate_uac3_feature_unit(const v    
214                                        const s    
215 {                                                 
216         const struct uac3_feature_unit_descrip    
217                                                   
218         if (d->bLength < sizeof(*d))              
219                 return false;                     
220         /* at least bmaControls(0) for master     
221         return d->bLength >= sizeof(*d) + 4 +     
222 }                                                 
223                                                   
224 static bool validate_midi_out_jack(const void     
225                                    const struc    
226 {                                                 
227         const struct usb_midi_out_jack_descrip    
228                                                   
229         return d->bLength >= sizeof(*d) &&        
230                 d->bLength >= sizeof(*d) + d->    
231 }                                                 
232                                                   
233 #define FIXED(p, t, s) { .protocol = (p), .typ    
234 #define FUNC(p, t, f) { .protocol = (p), .type    
235                                                   
236 static const struct usb_desc_validator audio_v    
237         /* UAC1 */                                
238         FUNC(UAC_VERSION_1, UAC_HEADER, valida    
239         FIXED(UAC_VERSION_1, UAC_INPUT_TERMINA    
240               struct uac_input_terminal_descri    
241         FIXED(UAC_VERSION_1, UAC_OUTPUT_TERMIN    
242               struct uac1_output_terminal_desc    
243         FUNC(UAC_VERSION_1, UAC_MIXER_UNIT, va    
244         FUNC(UAC_VERSION_1, UAC_SELECTOR_UNIT,    
245         FUNC(UAC_VERSION_1, UAC_FEATURE_UNIT,     
246         FUNC(UAC_VERSION_1, UAC1_PROCESSING_UN    
247         FUNC(UAC_VERSION_1, UAC1_EXTENSION_UNI    
248                                                   
249         /* UAC2 */                                
250         FIXED(UAC_VERSION_2, UAC_HEADER, struc    
251         FIXED(UAC_VERSION_2, UAC_INPUT_TERMINA    
252               struct uac2_input_terminal_descr    
253         FIXED(UAC_VERSION_2, UAC_OUTPUT_TERMIN    
254               struct uac2_output_terminal_desc    
255         FUNC(UAC_VERSION_2, UAC_MIXER_UNIT, va    
256         FUNC(UAC_VERSION_2, UAC_SELECTOR_UNIT,    
257         FUNC(UAC_VERSION_2, UAC_FEATURE_UNIT,     
258         /* UAC_VERSION_2, UAC2_EFFECT_UNIT: no    
259         FUNC(UAC_VERSION_2, UAC2_PROCESSING_UN    
260         FUNC(UAC_VERSION_2, UAC2_EXTENSION_UNI    
261         FIXED(UAC_VERSION_2, UAC2_CLOCK_SOURCE    
262               struct uac_clock_source_descript    
263         FUNC(UAC_VERSION_2, UAC2_CLOCK_SELECTO    
264         FIXED(UAC_VERSION_2, UAC2_CLOCK_MULTIP    
265               struct uac_clock_multiplier_desc    
266         /* UAC_VERSION_2, UAC2_SAMPLE_RATE_CON    
267                                                   
268         /* UAC3 */                                
269         FIXED(UAC_VERSION_2, UAC_HEADER, struc    
270         FIXED(UAC_VERSION_3, UAC_INPUT_TERMINA    
271               struct uac3_input_terminal_descr    
272         FIXED(UAC_VERSION_3, UAC_OUTPUT_TERMIN    
273               struct uac3_output_terminal_desc    
274         /* UAC_VERSION_3, UAC3_EXTENDED_TERMIN    
275         FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, v    
276         FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT    
277         FUNC(UAC_VERSION_3, UAC_FEATURE_UNIT,     
278         /*  UAC_VERSION_3, UAC3_EFFECT_UNIT: n    
279         FUNC(UAC_VERSION_3, UAC3_PROCESSING_UN    
280         FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNI    
281         FIXED(UAC_VERSION_3, UAC3_CLOCK_SOURCE    
282               struct uac3_clock_source_descrip    
283         FUNC(UAC_VERSION_3, UAC3_CLOCK_SELECTO    
284         FIXED(UAC_VERSION_3, UAC3_CLOCK_MULTIP    
285               struct uac3_clock_multiplier_des    
286         /* UAC_VERSION_3, UAC3_SAMPLE_RATE_CON    
287         /* UAC_VERSION_3, UAC3_CONNECTORS: not    
288         { } /* terminator */                      
289 };                                                
290                                                   
291 static const struct usb_desc_validator midi_va    
292         FIXED(UAC_VERSION_ALL, USB_MS_HEADER,     
293               struct usb_ms_header_descriptor)    
294         FIXED(UAC_VERSION_ALL, USB_MS_MIDI_IN_    
295               struct usb_midi_in_jack_descript    
296         FUNC(UAC_VERSION_ALL, USB_MS_MIDI_OUT_    
297              validate_midi_out_jack),             
298         { } /* terminator */                      
299 };                                                
300                                                   
301                                                   
302 /* Validate the given unit descriptor, return     
303 static bool validate_desc(unsigned char *hdr,     
304                           const struct usb_des    
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_VERSIO    
312                      v->protocol == protocol))    
313                         if (v->func)              
314                                 return v->func    
315                         /* check for the fixed    
316                         return hdr[0] >= v->si    
317                 }                                 
318         }                                         
319                                                   
320         return true; /* not matching, skip val    
321 }                                                 
322                                                   
323 bool snd_usb_validate_audio_desc(void *p, int     
324 {                                                 
325         unsigned char *c = p;                     
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 }                                                 
336                                                   
337 bool snd_usb_validate_midi_desc(void *p)          
338 {                                                 
339         unsigned char *c = p;                     
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 }                                                 
350                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php