Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
compat-openssl098.11471
openssl-CVE-2018-0739.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssl-CVE-2018-0739.patch of Package compat-openssl098.11471
commit 9310d45087ae546e27e61ddf8f6367f29848220d Author: Matt Caswell <matt@openssl.org> Date: Thu Mar 22 10:05:40 2018 +0000 Limit ASN.1 constructed types recursive definition depth Constructed types with a recursive definition (such as can be found in PKCS7) could eventually exceed the stack given malicious input with excessive recursion. Therefore we limit the stack depth. CVE-2018-0739 Credit to OSSFuzz for finding this issue. Reviewed-by: Rich Salz <rsalz@openssl.org> Index: openssl-0.9.8j/crypto/asn1/asn1.h =================================================================== --- openssl-0.9.8j.orig/crypto/asn1/asn1.h 2018-03-28 15:13:24.531593270 +0200 +++ openssl-0.9.8j/crypto/asn1/asn1.h 2018-03-28 15:13:25.967615686 +0200 @@ -1281,6 +1281,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_MSTRING_NOT_UNIVERSAL 139 #define ASN1_R_MSTRING_WRONG_TAG 140 #define ASN1_R_NESTED_ASN1_STRING 197 +#define ASN1_R_NESTED_TOO_DEEP 219 #define ASN1_R_NON_HEX_CHARACTERS 141 #define ASN1_R_NOT_ASCII_FORMAT 190 #define ASN1_R_NOT_ENOUGH_DATA 142 Index: openssl-0.9.8j/crypto/asn1/asn1_err.c =================================================================== --- openssl-0.9.8j.orig/crypto/asn1/asn1_err.c 2018-03-28 15:13:24.531593270 +0200 +++ openssl-0.9.8j/crypto/asn1/asn1_err.c 2018-03-28 15:13:25.967615686 +0200 @@ -258,6 +258,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"}, {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG) ,"mstring wrong tag"}, {ERR_REASON(ASN1_R_NESTED_ASN1_STRING) ,"nested asn1 string"}, +{ERR_REASON(ASN1_R_NESTED_TOO_DEEP) ,"nested too deep"}, {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"}, {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"}, {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"}, Index: openssl-0.9.8j/crypto/asn1/tasn_dec.c =================================================================== --- openssl-0.9.8j.orig/crypto/asn1/tasn_dec.c 2018-03-28 15:13:24.535593332 +0200 +++ openssl-0.9.8j/crypto/asn1/tasn_dec.c 2018-03-28 15:14:55.025027989 +0200 @@ -65,6 +65,14 @@ #include <openssl/buffer.h> #include <openssl/err.h> +/* + * Constructed types with a recursive definition (such as can be found in PKCS7) + * could eventually exceed the stack given malicious input with excessive + * recursion. Therefore we limit the stack depth. This is the maximum number of + * recursive invocations of asn1_item_embed_d2i(). + */ +#define ASN1_MAX_CONSTRUCTED_NEST 30 + static int asn1_check_eoc(const unsigned char **in, long len); static int asn1_find_end(const unsigned char **in, long len, char inf); @@ -77,16 +85,16 @@ static int asn1_check_tlen(long *olen, i char *inf, char *cst, const unsigned char **in, long len, int exptag, int expclass, char opt, - ASN1_TLC *ctx); + ASN1_TLC *ctx); static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx); + ASN1_TLC *ctx, int depth); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx); + ASN1_TLC *ctx, int depth); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, @@ -141,7 +149,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval, { ASN1_TLC c; c.valid = 0; - return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); + return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0); } @@ -149,9 +157,9 @@ int ASN1_template_d2i(ASN1_VALUE **pval, * If 'opt' set and tag mismatch return -1 to handle OPTIONAL */ -int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) +static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx, int depth) { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_COMPAT_FUNCS *cf; @@ -175,6 +183,11 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, asn1_cb = aux->asn1_cb; else asn1_cb = 0; + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP); + goto err; + } + switch(it->itype) { case ASN1_ITYPE_PRIMITIVE: @@ -193,7 +206,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, goto err; } return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx); + it->templates, opt, ctx, depth); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); @@ -334,7 +347,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, /* We mark field as OPTIONAL so its absence * can be recognised. */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); /* If field not present, try the next one */ if (ret == -1) continue; @@ -465,7 +478,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, * OPTIONAL */ ret = asn1_template_ex_d2i(pseqval, &p, len, - seqtt, isopt, ctx); + seqtt, isopt, ctx, depth); if (!ret) { errtt = seqtt; @@ -545,6 +558,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, return 0; } +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); +} + /* Templates are handled with two separate functions. * One handles any EXPLICIT tag and the other handles the rest. */ @@ -552,7 +572,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx) + ASN1_TLC *ctx, int depth) { int flags, aclass; int ret; @@ -592,7 +612,7 @@ static int asn1_template_ex_d2i(ASN1_VAL return 0; } /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, @@ -625,7 +645,7 @@ static int asn1_template_ex_d2i(ASN1_VAL } else return asn1_template_noexp_d2i(val, in, inlen, - tt, opt, ctx); + tt, opt, ctx, depth); *in = p; return 1; @@ -638,7 +658,7 @@ static int asn1_template_ex_d2i(ASN1_VAL static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx) + ASN1_TLC *ctx, int depth) { int flags, aclass; int ret; @@ -722,9 +742,9 @@ static int asn1_template_noexp_d2i(ASN1_ break; } skfield = NULL; - if (!ASN1_item_ex_d2i(&skfield, &p, len, + if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, 0, ctx)) + -1, 0, 0, ctx, depth)) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); @@ -747,8 +767,8 @@ static int asn1_template_noexp_d2i(ASN1_ else if (flags & ASN1_TFLG_IMPTAG) { /* IMPLICIT tagging */ - ret = ASN1_item_ex_d2i(val, &p, len, - ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); + ret = asn1_item_ex_d2i(val, &p, len, + ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, @@ -761,8 +781,8 @@ static int asn1_template_noexp_d2i(ASN1_ else { /* Nothing special */ - ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), + -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor