X.509: Fix indefinite length element skip error handling
asn1_find_indefinite_length() returns an error indicator of -1, which the caller asn1_ber_decoder() places in a size_t (which is usually unsigned) and then checks to see whether it is less than 0 (which it can't be). This can lead to the following warning: lib/asn1_decoder.c:320 asn1_ber_decoder() warn: unsigned 'len' is never less than zero. Instead, asn1_find_indefinite_length() update the caller's idea of the data cursor and length separately from returning the error code. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Родитель
2f1c4fef10
Коммит
dbadc17683
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче