@@ -395,12 +395,39 @@ static inline size_t fcgi_get_params_len( int *result, unsigned char *p, unsigne
395
395
return ret ;
396
396
}
397
397
398
+ static inline int fcgi_param_get_eff_len ( unsigned char * p , unsigned char * end , uint * eff_len )
399
+ {
400
+ int ret = 1 ;
401
+ int zero_found = 0 ;
402
+ * eff_len = 0 ;
403
+ for (; p != end ; ++ p ) {
404
+ if (* p == '\0' ) {
405
+ zero_found = 1 ;
406
+ }
407
+ else {
408
+ if (zero_found ) {
409
+ ret = 0 ;
410
+ break ;
411
+ }
412
+ if (* eff_len < ((uint )- 1 )) {
413
+ ++ * eff_len ;
414
+ }
415
+ else {
416
+ ret = 0 ;
417
+ break ;
418
+ }
419
+ }
420
+ }
421
+ return ret ;
422
+ }
423
+
398
424
static int fcgi_get_params (fcgi_request * req , unsigned char * p , unsigned char * end )
399
425
{
400
426
char buf [128 ];
401
427
char * tmp = buf ;
402
428
size_t buf_size = sizeof (buf );
403
429
int name_len , val_len ;
430
+ uint eff_name_len ;
404
431
char * s ;
405
432
int ret = 1 ;
406
433
size_t bytes_consumed ;
@@ -427,26 +454,35 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e
427
454
break ;
428
455
}
429
456
430
- if (name_len >= buf_size - 1 ) {
431
- if (name_len > ((uint )- 1 )- 64 ) {
457
+ /*
458
+ * get the effective length of the name in case it's not a valid string
459
+ * don't do this on the value because it can be binary data
460
+ */
461
+ if (!fcgi_param_get_eff_len (p , p + name_len , & eff_name_len )){
462
+ /* Malicious request */
463
+ ret = 0 ;
464
+ break ;
465
+ }
466
+ if (eff_name_len >= buf_size - 1 ) {
467
+ if (eff_name_len > ((uint )- 1 )- 64 ) {
432
468
ret = 0 ;
433
469
break ;
434
470
}
435
- buf_size = name_len + 64 ;
471
+ buf_size = eff_name_len + 64 ;
436
472
tmp = (tmp == buf ? emalloc (buf_size ): erealloc (tmp , buf_size ));
437
473
if (tmp == NULL ) {
438
474
ret = 0 ;
439
475
break ;
440
476
}
441
477
}
442
- memcpy (tmp , p , name_len );
443
- tmp [name_len ] = 0 ;
478
+ memcpy (tmp , p , eff_name_len );
479
+ tmp [eff_name_len ] = 0 ;
444
480
s = estrndup ((char * )p + name_len , val_len );
445
481
if (s == NULL ) {
446
482
ret = 0 ;
447
483
break ;
448
484
}
449
- zend_hash_update (req -> env , tmp , name_len + 1 , & s , sizeof (char * ), NULL );
485
+ zend_hash_update (req -> env , tmp , eff_name_len + 1 , & s , sizeof (char * ), NULL );
450
486
p += name_len + val_len ;
451
487
}
452
488
if (tmp != buf && tmp != NULL ) {
0 commit comments