summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Tetlow <gordon@FreeBSD.org>2020-12-14 21:20:55 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2020-12-14 21:20:55 +0000
commit4adbf1f6686ffdc4c0555a018e14ec63b5981534 (patch)
tree61d04488e5651afe6eb869adb24087363844ade0
parentebed16b75e77a115e6bb8106d0dbfa8223818032 (diff)
downloadsrc-test-releng/11.4.tar.gz
src-test-releng/11.4.zip
Fix OpenSSL NULL pointer de-reference.releng/11.4
Approved by: so Security: FreeBSD-SA-20:33.openssl Security: CVE-2020-1971
Notes
Notes: svn path=/releng/11.4/; revision=368643
-rw-r--r--UPDATING4
-rw-r--r--crypto/openssl/crypto/asn1/asn1.h2
-rw-r--r--crypto/openssl/crypto/asn1/asn1_err.c4
-rw-r--r--crypto/openssl/crypto/asn1/tasn_dec.c19
-rw-r--r--crypto/openssl/crypto/asn1/tasn_enc.c16
-rw-r--r--crypto/openssl/crypto/x509v3/v3_genn.c50
-rw-r--r--sys/conf/newvers.sh2
7 files changed, 90 insertions, 7 deletions
diff --git a/UPDATING b/UPDATING
index cdd6f80ce5de2..e648aa94e1d60 100644
--- a/UPDATING
+++ b/UPDATING
@@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITHOUT_CLANG and WITH_GCC to bootstrap to
the tip of head, and then rebuild without this option. The bootstrap process
from older version of current across the gcc/clang cutover is a bit fragile.
+20201215: p6 FreeBSD-SA-20:33.openssl
+
+ Fix OpenSSL NULL pointer de-reference. [SA-20:33.openssl]
+
20201201: p5 FreeBSD-EN-20:19.audit
FreeBSD-EN-20:20.tzdata
FreeBSD-EN-20:22.callout
diff --git a/crypto/openssl/crypto/asn1/asn1.h b/crypto/openssl/crypto/asn1/asn1.h
index 36e79d5ecd2db..a45687b0f0288 100644
--- a/crypto/openssl/crypto/asn1/asn1.h
+++ b/crypto/openssl/crypto/asn1/asn1.h
@@ -1203,6 +1203,7 @@ void ERR_load_ASN1_strings(void);
# define ASN1_F_ASN1_ITEM_DUP 191
# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121
# define ASN1_F_ASN1_ITEM_EX_D2I 120
+# define ASN1_F_ASN1_ITEM_EX_I2D 224
# define ASN1_F_ASN1_ITEM_I2D_BIO 192
# define ASN1_F_ASN1_ITEM_I2D_FP 193
# define ASN1_F_ASN1_ITEM_PACK 198
@@ -1304,6 +1305,7 @@ void ERR_load_ASN1_strings(void);
# define ASN1_R_BAD_OBJECT_HEADER 102
# define ASN1_R_BAD_PASSWORD_READ 103
# define ASN1_R_BAD_TAG 104
+# define ASN1_R_BAD_TEMPLATE 221
# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
# define ASN1_R_BN_LIB 105
# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
diff --git a/crypto/openssl/crypto/asn1/asn1_err.c b/crypto/openssl/crypto/asn1/asn1_err.c
index 9e273dcf5f235..54909d886e9df 100644
--- a/crypto/openssl/crypto/asn1/asn1_err.c
+++ b/crypto/openssl/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
- * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2020 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -103,6 +103,7 @@ static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_I2D), "ASN1_item_ex_i2d"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
@@ -207,6 +208,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"},
{ERR_REASON(ASN1_R_BAD_TAG), "bad tag"},
+ {ERR_REASON(ASN1_R_BAD_TEMPLATE), "bad template"},
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
"bmpstring is wrong length"},
{ERR_REASON(ASN1_R_BN_LIB), "bn lib"},
diff --git a/crypto/openssl/crypto/asn1/tasn_dec.c b/crypto/openssl/crypto/asn1/tasn_dec.c
index e657c36d8ab6d..cf7c9d52d0ca6 100644
--- a/crypto/openssl/crypto/asn1/tasn_dec.c
+++ b/crypto/openssl/crypto/asn1/tasn_dec.c
@@ -223,6 +223,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
break;
case ASN1_ITYPE_MSTRING:
+ /*
+ * It never makes sense for multi-strings to have implicit tagging, so
+ * if tag != -1, then this looks like an error in the template.
+ */
+ if (tag != -1) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_BAD_TEMPLATE);
+ goto err;
+ }
+
p = *in;
/* Just read in tag and class */
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
@@ -240,6 +249,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
}
+
/* Check tag matches bit map */
if (!(ASN1_tag2bit(otag) & it->utype)) {
/* If OPTIONAL, assume this is OK */
@@ -316,6 +326,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
goto err;
case ASN1_ITYPE_CHOICE:
+ /*
+ * It never makes sense for CHOICE types to have implicit tagging, so
+ * if tag != -1, then this looks like an error in the template.
+ */
+ if (tag != -1) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_BAD_TEMPLATE);
+ goto err;
+ }
+
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
if (*pval) {
diff --git a/crypto/openssl/crypto/asn1/tasn_enc.c b/crypto/openssl/crypto/asn1/tasn_enc.c
index 1824b2fc80f74..88c5d1914d071 100644
--- a/crypto/openssl/crypto/asn1/tasn_enc.c
+++ b/crypto/openssl/crypto/asn1/tasn_enc.c
@@ -151,9 +151,25 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
break;
case ASN1_ITYPE_MSTRING:
+ /*
+ * It never makes sense for multi-strings to have implicit tagging, so
+ * if tag != -1, then this looks like an error in the template.
+ */
+ if (tag != -1) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE);
+ return -1;
+ }
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
+ /*
+ * It never makes sense for CHOICE types to have implicit tagging, so
+ * if tag != -1, then this looks like an error in the template.
+ */
+ if (tag != -1) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE);
+ return -1;
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = asn1_get_choice_selector(pval, it);
diff --git a/crypto/openssl/crypto/x509v3/v3_genn.c b/crypto/openssl/crypto/x509v3/v3_genn.c
index 9bb01ee38e630..b96ed5eb16893 100644
--- a/crypto/openssl/crypto/x509v3/v3_genn.c
+++ b/crypto/openssl/crypto/x509v3/v3_genn.c
@@ -72,8 +72,9 @@ ASN1_SEQUENCE(OTHERNAME) = {
IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
ASN1_SEQUENCE(EDIPARTYNAME) = {
- ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
- ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+ /* DirectoryString is a CHOICE type so use explicit tagging */
+ ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+ ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
} ASN1_SEQUENCE_END(EDIPARTYNAME)
IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
@@ -107,6 +108,37 @@ GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
(char *)a);
}
+static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
+{
+ int res;
+
+ if (a == NULL || b == NULL) {
+ /*
+ * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
+ * anyway. OTHERNAME_cmp treats NULL != NULL so we do the same here
+ */
+ return -1;
+ }
+ if (a->nameAssigner == NULL && b->nameAssigner != NULL)
+ return -1;
+ if (a->nameAssigner != NULL && b->nameAssigner == NULL)
+ return 1;
+ /* If we get here then both have nameAssigner set, or both unset */
+ if (a->nameAssigner != NULL) {
+ res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
+ if (res != 0)
+ return res;
+ }
+ /*
+ * partyName is required, so these should never be NULL. We treat it in
+ * the same way as the a == NULL || b == NULL case above
+ */
+ if (a->partyName == NULL || b->partyName == NULL)
+ return -1;
+
+ return ASN1_STRING_cmp(a->partyName, b->partyName);
+}
+
/* Returns 0 if they are equal, != 0 otherwise. */
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
{
@@ -116,8 +148,11 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
return -1;
switch (a->type) {
case GEN_X400:
+ result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
+ break;
+
case GEN_EDIPARTY:
- result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+ result = edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName);
break;
case GEN_OTHERNAME:
@@ -164,8 +199,11 @@ void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
{
switch (type) {
case GEN_X400:
+ a->d.x400Address = value;
+ break;
+
case GEN_EDIPARTY:
- a->d.other = value;
+ a->d.ediPartyName = value;
break;
case GEN_OTHERNAME:
@@ -199,8 +237,10 @@ void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
*ptype = a->type;
switch (a->type) {
case GEN_X400:
+ return a->d.x400Address;
+
case GEN_EDIPARTY:
- return a->d.other;
+ return a->d.ediPartyName;
case GEN_OTHERNAME:
return a->d.otherName;
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 4db450c5157ec..5400423949cdc 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -44,7 +44,7 @@
TYPE="FreeBSD"
REVISION="11.4"
-BRANCH="RELEASE-p5"
+BRANCH="RELEASE-p6"
if [ -n "${BRANCH_OVERRIDE}" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi