10
10
#include <stdbool.h>
11
11
#include <unistd.h>
12
12
#include <string.h>
13
+ #include <limits.h>
13
14
14
15
#include <arpa/inet.h> /* ntohl */
15
16
37
38
#include "keys-gcrypt.c"
38
39
#endif
39
40
40
- void * reglib_get_file_ptr (uint8_t * db , int dblen , int structlen , uint32_t ptr )
41
+ void *
42
+ reglib_get_file_ptr (uint8_t * db , size_t dblen , size_t structlen , uint32_t ptr )
41
43
{
42
44
uint32_t p = ntohl (ptr );
43
45
46
+ if (structlen > dblen ) {
47
+ fprintf (stderr , "Invalid database file, too short!\n" );
48
+ exit (3 );
49
+ }
50
+
44
51
if (p > dblen - structlen ) {
45
52
fprintf (stderr , "Invalid database file, bad pointer!\n" );
46
53
exit (3 );
@@ -49,6 +56,17 @@ void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
49
56
return (void * )(db + p );
50
57
}
51
58
59
+ static size_t
60
+ reglib_array_len (size_t baselen , unsigned int elemcount , size_t elemlen )
61
+ {
62
+ if (elemcount > (SIZE_MAX - baselen ) / elemlen ) {
63
+ fprintf (stderr , "Invalid database file, count too large!\n" );
64
+ exit (3 );
65
+ }
66
+
67
+ return baselen + elemcount * elemlen ;
68
+ }
69
+
52
70
/*
53
71
* reglib_verify_db_signature():
54
72
*
@@ -59,7 +77,7 @@ void *reglib_get_file_ptr(uint8_t *db, int dblen, int structlen, uint32_t ptr)
59
77
*/
60
78
61
79
#ifdef USE_OPENSSL
62
- int reglib_verify_db_signature (uint8_t * db , int dblen , int siglen )
80
+ int reglib_verify_db_signature (uint8_t * db , size_t dblen , size_t siglen )
63
81
{
64
82
RSA * rsa ;
65
83
uint8_t hash [SHA_DIGEST_LENGTH ];
@@ -118,7 +136,7 @@ int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
118
136
#endif /* USE_OPENSSL */
119
137
120
138
#ifdef USE_GCRYPT
121
- int reglib_verify_db_signature (uint8_t * db , int dblen , int siglen )
139
+ int reglib_verify_db_signature (uint8_t * db , size_t dblen , size_t siglen )
122
140
{
123
141
gcry_mpi_t mpi_e , mpi_n ;
124
142
gcry_sexp_t rsa , signature , data ;
@@ -180,7 +198,7 @@ int reglib_verify_db_signature(uint8_t *db, int dblen, int siglen)
180
198
#endif /* USE_GCRYPT */
181
199
182
200
#if !defined(USE_OPENSSL ) && !defined(USE_GCRYPT )
183
- int reglib_verify_db_signature (uint8_t * db , int dblen , int siglen )
201
+ int reglib_verify_db_signature (uint8_t * db , size_t dblen , size_t siglen )
184
202
{
185
203
return 1 ;
186
204
}
@@ -220,7 +238,7 @@ const struct reglib_regdb_ctx *reglib_malloc_regdb_ctx(const char *regdb_file)
220
238
return NULL ;
221
239
}
222
240
223
- ctx -> header = reglib_get_file_ptr (ctx -> db , ctx -> dblen ,
241
+ ctx -> header = reglib_get_file_ptr (ctx -> db , ctx -> real_dblen ,
224
242
sizeof (struct regdb_file_header ),
225
243
0 );
226
244
header = ctx -> header ;
@@ -232,12 +250,13 @@ const struct reglib_regdb_ctx *reglib_malloc_regdb_ctx(const char *regdb_file)
232
250
goto err_out ;
233
251
234
252
ctx -> siglen = ntohl (header -> signature_length );
235
- /* The actual dblen does not take into account the signature */
236
- ctx -> dblen = ctx -> real_dblen - ctx -> siglen ;
237
253
238
- if (ctx -> dblen <= sizeof (* header ))
254
+ if (ctx -> siglen > ctx -> real_dblen - sizeof (* header ))
239
255
goto err_out ;
240
256
257
+ /* The actual dblen does not take into account the signature */
258
+ ctx -> dblen = ctx -> real_dblen - ctx -> siglen ;
259
+
241
260
/* verify signature */
242
261
if (!reglib_verify_db_signature (ctx -> db , ctx -> dblen , ctx -> siglen ))
243
262
goto err_out ;
@@ -272,7 +291,7 @@ void reglib_free_regdb_ctx(const struct reglib_regdb_ctx *regdb_ctx)
272
291
free (ctx );
273
292
}
274
293
275
- static void reg_rule2rd (uint8_t * db , int dblen ,
294
+ static void reg_rule2rd (uint8_t * db , size_t dblen ,
276
295
uint32_t ruleptr , struct ieee80211_reg_rule * rd_reg_rule )
277
296
{
278
297
struct regdb_file_reg_rule * rule ;
@@ -303,18 +322,21 @@ country2rd(const struct reglib_regdb_ctx *ctx,
303
322
{
304
323
struct regdb_file_reg_rules_collection * rcoll ;
305
324
struct ieee80211_regdomain * rd ;
306
- int i , num_rules , size_of_rd ;
325
+ unsigned int i , num_rules ;
326
+ size_t size_of_rd ;
307
327
308
328
rcoll = reglib_get_file_ptr (ctx -> db , ctx -> dblen , sizeof (* rcoll ),
309
329
country -> reg_collection_ptr );
310
330
num_rules = ntohl (rcoll -> reg_rule_num );
311
331
/* re-get pointer with sanity checking for num_rules */
312
332
rcoll = reglib_get_file_ptr (ctx -> db , ctx -> dblen ,
313
- sizeof (* rcoll ) + num_rules * sizeof (uint32_t ),
314
- country -> reg_collection_ptr );
333
+ reglib_array_len (sizeof (* rcoll ), num_rules ,
334
+ sizeof (uint32_t )),
335
+ country -> reg_collection_ptr );
315
336
316
- size_of_rd = sizeof (struct ieee80211_regdomain ) +
317
- num_rules * sizeof (struct ieee80211_reg_rule );
337
+ size_of_rd = reglib_array_len (sizeof (struct ieee80211_regdomain ),
338
+ num_rules ,
339
+ sizeof (struct ieee80211_reg_rule ));
318
340
319
341
rd = malloc (size_of_rd );
320
342
if (!rd )
@@ -468,7 +490,8 @@ struct ieee80211_regdomain *
468
490
reglib_intersect_rds (const struct ieee80211_regdomain * rd1 ,
469
491
const struct ieee80211_regdomain * rd2 )
470
492
{
471
- int r , size_of_regd ;
493
+ int r ;
494
+ size_t size_of_regd ;
472
495
unsigned int x , y ;
473
496
unsigned int num_rules = 0 , rule_idx = 0 ;
474
497
const struct ieee80211_reg_rule * rule1 , * rule2 ;
@@ -506,8 +529,9 @@ reglib_intersect_rds(const struct ieee80211_regdomain *rd1,
506
529
if (!num_rules )
507
530
return NULL ;
508
531
509
- size_of_regd = sizeof (struct ieee80211_regdomain ) +
510
- ((num_rules + 1 ) * sizeof (struct ieee80211_reg_rule ));
532
+ size_of_regd = reglib_array_len (sizeof (struct ieee80211_regdomain ),
533
+ num_rules + 1 ,
534
+ sizeof (struct ieee80211_reg_rule ));
511
535
512
536
rd = malloc (size_of_regd );
513
537
if (!rd )
0 commit comments