8
|
1 |
|
|
2 |
#At file:///home/ram/mysql/b50227-5.0-bugteam/ based on revid:gshchepa@stripped
|
|
3 |
|
|
4 |
2838 Ramil Kalimullin 2010-01-13
|
|
5 |
Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL
|
|
6 |
|
|
7 |
Problem: copying issuer's (or subject's) name tags into an internal
|
|
8 |
buffer from incoming stream we didn't check the buffer overflow.
|
|
9 |
That may lead to memory overrun, crash etc.
|
|
10 |
|
|
11 |
Fix: ensure we don't overrun the buffer.
|
|
12 |
|
|
13 |
Note: there's no simple test case (exploit needed).
|
|
14 |
@ extra/yassl/taocrypt/include/asn.hpp
|
|
15 |
Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL
|
|
16 |
- CertDecoder::AddTag() introduced.
|
|
17 |
@ extra/yassl/taocrypt/src/asn.cpp
|
|
18 |
Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL
|
|
19 |
- copying data from incoming stream to the issuer_ or subject_
|
|
20 |
buffers ensure we don't overrun them.
|
|
21 |
- code cleanup.
|
|
22 |
|
|
23 |
modified:
|
|
24 |
extra/yassl/taocrypt/include/asn.hpp
|
|
25 |
extra/yassl/taocrypt/src/asn.cpp
|
|
26 |
=== modified file 'extra/yassl/taocrypt/include/asn.hpp'
|
|
27 |
--- a/extra/yassl/taocrypt/include/asn.hpp 2007-01-29 15:54:40 +0000
|
|
28 |
+++ b/extra/yassl/taocrypt/include/asn.hpp 2010-01-13 05:20:45 +0000
|
|
29 |
@@ -305,6 +305,7 @@ private:
|
|
30 |
bool ValidateSignature(SignerList*);
|
|
31 |
bool ConfirmSignature(Source&);
|
|
32 |
void GetKey();
|
|
33 |
+ char* AddTag(char*, const char*, const char*, word32, word32);
|
|
34 |
void GetName(NameType);
|
|
35 |
void GetValidity();
|
|
36 |
void GetDate(DateType);
|
|
37 |
|
|
38 |
=== modified file 'extra/yassl/taocrypt/src/asn.cpp'
|
|
39 |
--- a/extra/yassl/taocrypt/src/asn.cpp 2009-06-29 13:17:01 +0000
|
|
40 |
+++ b/extra/yassl/taocrypt/src/asn.cpp 2010-01-13 05:20:45 +0000
|
|
41 |
@@ -652,6 +652,23 @@ word32 CertDecoder::GetDigest()
|
|
42 |
}
|
|
43 |
|
|
44 |
|
|
45 |
+char *CertDecoder::AddTag(char *ptr, const char *buf_end,
|
|
46 |
+ const char *tag_name, word32 tag_name_length,
|
|
47 |
+ word32 tag_value_length)
|
|
48 |
+{
|
|
49 |
+ if (ptr + tag_name_length + tag_value_length > buf_end)
|
|
50 |
+ return 0;
|
|
51 |
+
|
|
52 |
+ memcpy(ptr, tag_name, tag_name_length);
|
|
53 |
+ ptr+= tag_name_length;
|
|
54 |
+
|
|
55 |
+ memcpy(ptr, source_.get_current(), tag_value_length);
|
|
56 |
+ ptr+= tag_value_length;
|
|
57 |
+
|
|
58 |
+ return ptr;
|
|
59 |
+}
|
|
60 |
+
|
|
61 |
+
|
|
62 |
// process NAME, either issuer or subject
|
|
63 |
void CertDecoder::GetName(NameType nt)
|
|
64 |
{
|
|
65 |
@@ -659,11 +676,21 @@ void CertDecoder::GetName(NameType nt)
|
|
66 |
|
|
67 |
SHA sha;
|
|
68 |
word32 length = GetSequence(); // length of all distinguished names
|
|
69 |
- assert (length < ASN_NAME_MAX);
|
|
70 |
+
|
|
71 |
+ if (length >= ASN_NAME_MAX)
|
|
72 |
+ goto err;
|
|
73 |
length += source_.get_index();
|
|
74 |
|
|
75 |
- char* ptr = (nt == ISSUER) ? issuer_ : subject_;
|
|
76 |
- word32 idx = 0;
|
|
77 |
+ char *ptr, *buf_end;
|
|
78 |
+
|
|
79 |
+ if (nt == ISSUER) {
|
|
80 |
+ ptr= issuer_;
|
|
81 |
+ buf_end= ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0
|
|
82 |
+ }
|
|
83 |
+ else {
|
|
84 |
+ ptr= subject_;
|
|
85 |
+ buf_end= ptr + sizeof(subject_) - 1; // 1 byte for trailing 0
|
|
86 |
+ }
|
|
87 |
|
|
88 |
while (source_.get_index() < length) {
|
|
89 |
GetSet();
|
|
90 |
@@ -685,47 +712,36 @@ void CertDecoder::GetName(NameType nt)
|
|
91 |
byte id = source_.next();
|
|
92 |
b = source_.next(); // strType
|
|
93 |
word32 strLen = GetLength(source_);
|
|
94 |
- bool copy = false;
|
|
95 |
|
|
96 |
- if (id == COMMON_NAME) {
|
|
97 |
- memcpy(&ptr[idx], "/CN=", 4);
|
|
98 |
- idx += 4;
|
|
99 |
- copy = true;
|
|
100 |
- }
|
|
101 |
- else if (id == SUR_NAME) {
|
|
102 |
- memcpy(&ptr[idx], "/SN=", 4);
|
|
103 |
- idx += 4;
|
|
104 |
- copy = true;
|
|
105 |
- }
|
|
106 |
- else if (id == COUNTRY_NAME) {
|
|
107 |
- memcpy(&ptr[idx], "/C=", 3);
|
|
108 |
- idx += 3;
|
|
109 |
- copy = true;
|
|
110 |
- }
|
|
111 |
- else if (id == LOCALITY_NAME) {
|
|
112 |
- memcpy(&ptr[idx], "/L=", 3);
|
|
113 |
- idx += 3;
|
|
114 |
- copy = true;
|
|
115 |
- }
|
|
116 |
- else if (id == STATE_NAME) {
|
|
117 |
- memcpy(&ptr[idx], "/ST=", 4);
|
|
118 |
- idx += 4;
|
|
119 |
- copy = true;
|
|
120 |
- }
|
|
121 |
- else if (id == ORG_NAME) {
|
|
122 |
- memcpy(&ptr[idx], "/O=", 3);
|
|
123 |
- idx += 3;
|
|
124 |
- copy = true;
|
|
125 |
- }
|
|
126 |
- else if (id == ORGUNIT_NAME) {
|
|
127 |
- memcpy(&ptr[idx], "/OU=", 4);
|
|
128 |
- idx += 4;
|
|
129 |
- copy = true;
|
|
130 |
- }
|
|
131 |
-
|
|
132 |
- if (copy) {
|
|
133 |
- memcpy(&ptr[idx], source_.get_current(), strLen);
|
|
134 |
- idx += strLen;
|
|
135 |
+ switch (id) {
|
|
136 |
+ case COMMON_NAME:
|
|
137 |
+ if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen)))
|
|
138 |
+ goto err;
|
|
139 |
+ break;
|
|
140 |
+ case SUR_NAME:
|
|
141 |
+ if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen)))
|
|
142 |
+ goto err;
|
|
143 |
+ break;
|
|
144 |
+ case COUNTRY_NAME:
|
|
145 |
+ if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen)))
|
|
146 |
+ goto err;
|
|
147 |
+ break;
|
|
148 |
+ case LOCALITY_NAME:
|
|
149 |
+ if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen)))
|
|
150 |
+ goto err;
|
|
151 |
+ break;
|
|
152 |
+ case STATE_NAME:
|
|
153 |
+ if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen)))
|
|
154 |
+ goto err;
|
|
155 |
+ break;
|
|
156 |
+ case ORG_NAME:
|
|
157 |
+ if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen)))
|
|
158 |
+ goto err;
|
|
159 |
+ break;
|
|
160 |
+ case ORGUNIT_NAME:
|
|
161 |
+ if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen)))
|
|
162 |
+ goto err;
|
|
163 |
+ break;
|
|
164 |
}
|
|
165 |
|
|
166 |
sha.Update(source_.get_current(), strLen);
|
|
167 |
@@ -739,23 +755,20 @@ void CertDecoder::GetName(NameType nt)
|
|
168 |
source_.advance(oidSz + 1);
|
|
169 |
word32 length = GetLength(source_);
|
|
170 |
|
|
171 |
- if (email) {
|
|
172 |
- memcpy(&ptr[idx], "/emailAddress=", 14);
|
|
173 |
- idx += 14;
|
|
174 |
-
|
|
175 |
- memcpy(&ptr[idx], source_.get_current(), length);
|
|
176 |
- idx += length;
|
|
177 |
- }
|
|
178 |
+ if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length)))
|
|
179 |
+ goto err;
|
|
180 |
|
|
181 |
source_.advance(length);
|
|
182 |
}
|
|
183 |
}
|
|
184 |
- ptr[idx++] = 0;
|
|
185 |
+ *ptr= 0;
|
|
186 |
|
|
187 |
- if (nt == ISSUER)
|
|
188 |
- sha.Final(issuerHash_);
|
|
189 |
- else
|
|
190 |
- sha.Final(subjectHash_);
|
|
191 |
+ sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_);
|
|
192 |
+
|
|
193 |
+ return;
|
|
194 |
+
|
|
195 |
+err:
|
|
196 |
+ source_.SetError(CONTENT_E);
|
|
197 |
}
|
|
198 |
|