diff options
Diffstat (limited to 'lib/asn1_decoder.c')
| -rw-r--r-- | lib/asn1_decoder.c | 28 | 
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index 2e4196ddf06..de2c8b5a715 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c @@ -46,12 +46,18 @@ static const unsigned char asn1_op_lengths[ASN1_OP__NR] = {  /*   * Find the length of an indefinite length object + * @data: The data buffer + * @datalen: The end of the innermost containing element in the buffer + * @_dp: The data parse cursor (updated before returning) + * @_len: Where to return the size of the element. + * @_errmsg: Where to return a pointer to an error message on error   */  static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen, -				       const char **_errmsg, size_t *_err_dp) +				       size_t *_dp, size_t *_len, +				       const char **_errmsg)  {  	unsigned char tag, tmp; -	size_t dp = 0, len, n; +	size_t dp = *_dp, len, n;  	int indef_level = 1;  next_tag: @@ -67,8 +73,11 @@ next_tag:  		/* It appears to be an EOC. */  		if (data[dp++] != 0)  			goto invalid_eoc; -		if (--indef_level <= 0) -			return dp; +		if (--indef_level <= 0) { +			*_len = dp - *_dp; +			*_dp = dp; +			return 0; +		}  		goto next_tag;  	} @@ -122,7 +131,7 @@ data_overrun_error:  missing_eoc:  	*_errmsg = "Missing EOC in indefinite len cons";  error: -	*_err_dp = dp; +	*_dp = dp;  	return -1;  } @@ -315,13 +324,14 @@ next_op:  	skip_data:  		if (!(flags & FLAG_CONS)) {  			if (flags & FLAG_INDEFINITE_LENGTH) { -				len = asn1_find_indefinite_length( -					data + dp, datalen - dp, &errmsg, &dp); -				if (len < 0) +				ret = asn1_find_indefinite_length( +					data, datalen, &dp, &len, &errmsg); +				if (ret < 0)  					goto error; +			} else { +				dp += len;  			}  			pr_debug("- LEAF: %zu\n", len); -			dp += len;  		}  		pc += asn1_op_lengths[op];  		goto next_op;  |