3030
3131#define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */
3232
33+ /* Variable Length Array Macros **********************************************/
34+ #define vla_group (groupname ) size_t groupname##__next = 0
35+ #define vla_group_size (groupname ) groupname##__next
36+
37+ #define vla_item (groupname , type , name , n ) \
38+ size_t groupname##_##name##__offset = ({ \
39+ size_t align_mask = __alignof__(type) - 1; \
40+ size_t offset = (groupname##__next + align_mask) & ~align_mask;\
41+ size_t size = (n) * sizeof(type); \
42+ groupname##__next = offset + size; \
43+ offset; \
44+ })
45+
46+ #define vla_item_with_sz (groupname , type , name , n ) \
47+ size_t groupname##_##name##__sz = (n) * sizeof(type); \
48+ size_t groupname##_##name##__offset = ({ \
49+ size_t align_mask = __alignof__(type) - 1; \
50+ size_t offset = (groupname##__next + align_mask) & ~align_mask;\
51+ size_t size = groupname##_##name##__sz; \
52+ groupname##__next = offset + size; \
53+ offset; \
54+ })
55+
56+ #define vla_ptr (ptr , groupname , name ) \
57+ ((void *) ((char *)ptr + groupname##_##name##__offset))
3358
3459/* Debugging ****************************************************************/
3560
@@ -1902,30 +1927,34 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
19021927
19031928 /* Allocate everything in one chunk so there's less maintenance. */
19041929 {
1905- struct {
1906- struct usb_gadget_strings * stringtabs [lang_count + 1 ];
1907- struct usb_gadget_strings stringtab [lang_count ];
1908- struct usb_string strings [lang_count * (needed_count + 1 )];
1909- } * d ;
19101930 unsigned i = 0 ;
1931+ vla_group (d );
1932+ vla_item (d , struct usb_gadget_strings * , stringtabs ,
1933+ lang_count + 1 );
1934+ vla_item (d , struct usb_gadget_strings , stringtab , lang_count );
1935+ vla_item (d , struct usb_string , strings ,
1936+ lang_count * (needed_count + 1 ));
19111937
1912- d = kmalloc (sizeof * d , GFP_KERNEL );
1913- if (unlikely (!d )) {
1938+ char * vlabuf = kmalloc (vla_group_size (d ), GFP_KERNEL );
1939+
1940+ if (unlikely (!vlabuf )) {
19141941 kfree (_data );
19151942 return - ENOMEM ;
19161943 }
19171944
1918- stringtabs = d -> stringtabs ;
1919- t = d -> stringtab ;
1945+ /* Initialize the VLA pointers */
1946+ stringtabs = vla_ptr (vlabuf , d , stringtabs );
1947+ t = vla_ptr (vlabuf , d , stringtab );
19201948 i = lang_count ;
19211949 do {
19221950 * stringtabs ++ = t ++ ;
19231951 } while (-- i );
19241952 * stringtabs = NULL ;
19251953
1926- stringtabs = d -> stringtabs ;
1927- t = d -> stringtab ;
1928- s = d -> strings ;
1954+ /* stringtabs = vlabuf = d_stringtabs for later kfree */
1955+ stringtabs = vla_ptr (vlabuf , d , stringtabs );
1956+ t = vla_ptr (vlabuf , d , stringtab );
1957+ s = vla_ptr (vlabuf , d , strings );
19291958 strings = s ;
19301959 }
19311960
@@ -2201,49 +2230,56 @@ static int ffs_func_bind(struct usb_configuration *c,
22012230 int ret ;
22022231
22032232 /* Make it a single chunk, less management later on */
2204- struct {
2205- struct ffs_ep eps [ ffs -> eps_count ] ;
2206- struct usb_descriptor_header
2207- * fs_descs [ full ? ffs -> fs_descs_count + 1 : 0 ] ;
2208- struct usb_descriptor_header
2209- * hs_descs [ high ? ffs -> hs_descs_count + 1 : 0 ] ;
2210- short inums [ ffs -> interfaces_count ] ;
2211- char raw_descs [ high ? ffs -> raw_descs_length
2212- : ffs -> raw_fs_descs_length ] ;
2213- } * data ;
2233+ vla_group ( d );
2234+ vla_item_with_sz ( d , struct ffs_ep , eps , ffs -> eps_count ) ;
2235+ vla_item_with_sz ( d , struct usb_descriptor_header * , fs_descs ,
2236+ full ? ffs -> fs_descs_count + 1 : 0 ) ;
2237+ vla_item_with_sz ( d , struct usb_descriptor_header * , hs_descs ,
2238+ high ? ffs -> hs_descs_count + 1 : 0 ) ;
2239+ vla_item_with_sz ( d , short , inums , ffs -> interfaces_count ) ;
2240+ vla_item_with_sz ( d , char , raw_descs ,
2241+ high ? ffs -> raw_descs_length : ffs -> raw_fs_descs_length ) ;
2242+ char * vlabuf ;
22142243
22152244 ENTER ();
22162245
22172246 /* Only high speed but not supported by gadget? */
22182247 if (unlikely (!(full | high )))
22192248 return - ENOTSUPP ;
22202249
2221- /* Allocate */
2222- data = kmalloc (sizeof * data , GFP_KERNEL );
2223- if (unlikely (!data ))
2250+ /* Allocate a single chunk, less management later on */
2251+ vlabuf = kmalloc (vla_group_size ( d ) , GFP_KERNEL );
2252+ if (unlikely (!vlabuf ))
22242253 return - ENOMEM ;
22252254
22262255 /* Zero */
2227- memset (data -> eps , 0 , sizeof data -> eps );
2228- memcpy (data -> raw_descs , ffs -> raw_descs + 16 , sizeof data -> raw_descs );
2229- memset (data -> inums , 0xff , sizeof data -> inums );
2230- for (ret = ffs -> eps_count ; ret ; -- ret )
2231- data -> eps [ret ].num = -1 ;
2256+ memset (vla_ptr (vlabuf , d , eps ), 0 , d_eps__sz );
2257+ memcpy (vla_ptr (vlabuf , d , raw_descs ), ffs -> raw_descs + 16 ,
2258+ d_raw_descs__sz );
2259+ memset (vla_ptr (vlabuf , d , inums ), 0xff , d_inums__sz );
2260+ for (ret = ffs -> eps_count ; ret ; -- ret ) {
2261+ struct ffs_ep * ptr ;
2262+
2263+ ptr = vla_ptr (vlabuf , d , eps );
2264+ ptr [ret ].num = -1 ;
2265+ }
22322266
2233- /* Save pointers */
2234- func -> eps = data -> eps ;
2235- func -> interfaces_nums = data -> inums ;
2267+ /* Save pointers
2268+ * d_eps == vlabuf, func->eps used to kfree vlabuf later
2269+ */
2270+ func -> eps = vla_ptr (vlabuf , d , eps );
2271+ func -> interfaces_nums = vla_ptr (vlabuf , d , inums );
22362272
22372273 /*
22382274 * Go through all the endpoint descriptors and allocate
22392275 * endpoints first, so that later we can rewrite the endpoint
22402276 * numbers without worrying that it may be described later on.
22412277 */
22422278 if (likely (full )) {
2243- func -> function .fs_descriptors = data -> fs_descs ;
2279+ func -> function .fs_descriptors = vla_ptr ( vlabuf , d , fs_descs ) ;
22442280 ret = ffs_do_descs (ffs -> fs_descs_count ,
2245- data -> raw_descs ,
2246- sizeof data -> raw_descs ,
2281+ vla_ptr ( vlabuf , d , raw_descs ) ,
2282+ d_raw_descs__sz ,
22472283 __ffs_func_bind_do_descs , func );
22482284 if (unlikely (ret < 0 ))
22492285 goto error ;
@@ -2252,10 +2288,10 @@ static int ffs_func_bind(struct usb_configuration *c,
22522288 }
22532289
22542290 if (likely (high )) {
2255- func -> function .hs_descriptors = data -> hs_descs ;
2291+ func -> function .hs_descriptors = vla_ptr ( vlabuf , d , hs_descs ) ;
22562292 ret = ffs_do_descs (ffs -> hs_descs_count ,
2257- data -> raw_descs + ret ,
2258- ( sizeof data -> raw_descs ) - ret ,
2293+ vla_ptr ( vlabuf , d , raw_descs ) + ret ,
2294+ d_raw_descs__sz - ret ,
22592295 __ffs_func_bind_do_descs , func );
22602296 if (unlikely (ret < 0 ))
22612297 goto error ;
@@ -2268,7 +2304,7 @@ static int ffs_func_bind(struct usb_configuration *c,
22682304 */
22692305 ret = ffs_do_descs (ffs -> fs_descs_count +
22702306 (high ? ffs -> hs_descs_count : 0 ),
2271- data -> raw_descs , sizeof data -> raw_descs ,
2307+ vla_ptr ( vlabuf , d , raw_descs ), d_raw_descs__sz ,
22722308 __ffs_func_bind_do_nums , func );
22732309 if (unlikely (ret < 0 ))
22742310 goto error ;
0 commit comments