1
Origin: http://cvs.openssl.org/chngview?cn=21937
2
Subject: Prevent malformed RFC3779 data triggering an assertion failure
6
[Ubuntu note: dropped CHANGES file modifications to reduce patch conflicts.]
9
crypto/x509v3/v3_addr.c | 74 ++++++++++++++++++++++++++++++------------------
10
1 file changed, 47 insertions(+), 27 deletions(-)
12
Index: b/crypto/x509v3/v3_addr.c
13
===================================================================
14
--- a/crypto/x509v3/v3_addr.c
15
+++ b/crypto/x509v3/v3_addr.c
16
@@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAdd
17
* Expand the bitstring form of an address into a raw byte array.
18
* At the moment this is coded for simplicity, not speed.
20
-static void addr_expand(unsigned char *addr,
21
+static int addr_expand(unsigned char *addr,
22
const ASN1_BIT_STRING *bs,
24
const unsigned char fill)
26
- OPENSSL_assert(bs->length >= 0 && bs->length <= length);
27
+ if (bs->length < 0 || bs->length > length)
30
memcpy(addr, bs->data, bs->length);
31
if ((bs->flags & 7) != 0) {
32
@@ -159,6 +160,7 @@ static void addr_expand(unsigned char *a
35
memset(addr + bs->length, fill, length - bs->length);
40
@@ -179,11 +181,13 @@ static int i2r_address(BIO *out,
44
- addr_expand(addr, bs, 4, fill);
45
+ if (!addr_expand(addr, bs, 4, fill))
47
BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
50
- addr_expand(addr, bs, 16, fill);
51
+ if (!addr_expand(addr, bs, 16, fill))
53
for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
55
for (i = 0; i < n; i += 2)
56
@@ -309,6 +313,12 @@ static int i2r_IPAddrBlocks(X509V3_EXT_M
58
* Sort comparison function for a sequence of IPAddressOrRange
61
+ * There's no sane answer we can give if addr_expand() fails, and an
62
+ * assertion failure on externally supplied data is seriously uncool,
63
+ * so we just arbitrarily declare that if given invalid inputs this
64
+ * function returns -1. If this messes up your preferred sort order
65
+ * for garbage input, tough noogies.
67
static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
68
const IPAddressOrRange *b,
69
@@ -321,22 +331,26 @@ static int IPAddressOrRange_cmp(const IP
72
case IPAddressOrRange_addressPrefix:
73
- addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
74
+ if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
76
prefixlen_a = addr_prefixlen(a->u.addressPrefix);
78
case IPAddressOrRange_addressRange:
79
- addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
80
+ if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
82
prefixlen_a = length * 8;
87
case IPAddressOrRange_addressPrefix:
88
- addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
89
+ if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
91
prefixlen_b = addr_prefixlen(b->u.addressPrefix);
93
case IPAddressOrRange_addressRange:
94
- addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
95
+ if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
97
prefixlen_b = length * 8;
100
@@ -651,22 +665,22 @@ int v3_addr_add_range(IPAddrBlocks *addr
102
* Extract min and max values from an IPAddressOrRange.
104
-static void extract_min_max(IPAddressOrRange *aor,
105
+static int extract_min_max(IPAddressOrRange *aor,
110
- OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
111
+ if (aor == NULL || min == NULL || max == NULL)
114
case IPAddressOrRange_addressPrefix:
115
- addr_expand(min, aor->u.addressPrefix, length, 0x00);
116
- addr_expand(max, aor->u.addressPrefix, length, 0xFF);
118
+ return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
119
+ addr_expand(max, aor->u.addressPrefix, length, 0xFF));
120
case IPAddressOrRange_addressRange:
121
- addr_expand(min, aor->u.addressRange->min, length, 0x00);
122
- addr_expand(max, aor->u.addressRange->max, length, 0xFF);
124
+ return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
125
+ addr_expand(max, aor->u.addressRange->max, length, 0xFF));
131
@@ -682,9 +696,10 @@ int v3_addr_get_range(IPAddressOrRange *
132
if (aor == NULL || min == NULL || max == NULL ||
133
afi_length == 0 || length < afi_length ||
134
(aor->type != IPAddressOrRange_addressPrefix &&
135
- aor->type != IPAddressOrRange_addressRange))
136
+ aor->type != IPAddressOrRange_addressRange) ||
137
+ !extract_min_max(aor, min, max, afi_length))
139
- extract_min_max(aor, min, max, afi_length);
144
@@ -766,8 +781,9 @@ int v3_addr_is_canonical(IPAddrBlocks *a
145
IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
146
IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
148
- extract_min_max(a, a_min, a_max, length);
149
- extract_min_max(b, b_min, b_max, length);
150
+ if (!extract_min_max(a, a_min, a_max, length) ||
151
+ !extract_min_max(b, b_min, b_max, length))
155
* Punt misordered list, overlapping start, or inverted range.
156
@@ -801,7 +817,8 @@ int v3_addr_is_canonical(IPAddrBlocks *a
158
IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
159
if (a->type == IPAddressOrRange_addressRange) {
160
- extract_min_max(a, a_min, a_max, length);
161
+ if (!extract_min_max(a, a_min, a_max, length))
163
if (range_should_be_prefix(a_min, a_max, length) >= 0)
166
@@ -836,8 +853,9 @@ static int IPAddressOrRanges_canonize(IP
167
unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
168
unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
170
- extract_min_max(a, a_min, a_max, length);
171
- extract_min_max(b, b_min, b_max, length);
172
+ if (!extract_min_max(a, a_min, a_max, length) ||
173
+ !extract_min_max(b, b_min, b_max, length))
178
@@ -1097,13 +1115,15 @@ static int addr_contains(IPAddressOrRang
181
for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
182
- extract_min_max(sk_IPAddressOrRange_value(child, c),
183
- c_min, c_max, length);
184
+ if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
185
+ c_min, c_max, length))
188
if (p >= sk_IPAddressOrRange_num(parent))
190
- extract_min_max(sk_IPAddressOrRange_value(parent, p),
191
- p_min, p_max, length);
192
+ if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
193
+ p_min, p_max, length))
195
if (memcmp(p_max, c_max, length) < 0)
197
if (memcmp(p_min, c_min, length) > 0)