1 |
commit: e71df7341cdaa0a4cc2aeff56496ce1724b921d2 |
2 |
Author: Wes Cilldhaire <wes <AT> sol1 <DOT> com <DOT> au> |
3 |
AuthorDate: Mon Feb 5 01:07:25 2018 +0000 |
4 |
Commit: Patrice Clement <monsieurp <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Feb 5 21:50:03 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=e71df734 |
7 |
|
8 |
net-nds/389-ds-base: patch against CVE-2017-15135 in 1.3.6.8. |
9 |
|
10 |
* Patch and revbump to 1.3.6.8 to address CVE-2017-15135 |
11 |
* Update copyright line in all versions for 2018 |
12 |
|
13 |
Bug: https://bugs.gentoo.org/645706 |
14 |
|
15 |
Acked-by: wibrown <AT> redhat.com |
16 |
Package-Manager: Portage-2.3.20, Repoman-2.3.6 |
17 |
Closes: https://github.com/gentoo/gentoo/pull/7078 |
18 |
|
19 |
net-nds/389-ds-base/389-ds-base-1.3.5.19.ebuild | 2 +- |
20 |
....3.6.8.ebuild => 389-ds-base-1.3.6.8-r1.ebuild} | 4 +- |
21 |
net-nds/389-ds-base/389-ds-base-9999.ebuild | 2 +- |
22 |
...-base-1.3.6-backport-invalid-password-mig.patch | 376 +++++++++++++++++++++ |
23 |
4 files changed, 381 insertions(+), 3 deletions(-) |
24 |
|
25 |
diff --git a/net-nds/389-ds-base/389-ds-base-1.3.5.19.ebuild b/net-nds/389-ds-base/389-ds-base-1.3.5.19.ebuild |
26 |
index 6fddd0315a5..e36a909ca91 100644 |
27 |
--- a/net-nds/389-ds-base/389-ds-base-1.3.5.19.ebuild |
28 |
+++ b/net-nds/389-ds-base/389-ds-base-1.3.5.19.ebuild |
29 |
@@ -1,4 +1,4 @@ |
30 |
-# Copyright 1999-2017 Gentoo Foundation |
31 |
+# Copyright 1999-2018 Gentoo Foundation |
32 |
# Distributed under the terms of the GNU General Public License v2 |
33 |
|
34 |
EAPI=5 |
35 |
|
36 |
diff --git a/net-nds/389-ds-base/389-ds-base-1.3.6.8.ebuild b/net-nds/389-ds-base/389-ds-base-1.3.6.8-r1.ebuild |
37 |
similarity index 96% |
38 |
rename from net-nds/389-ds-base/389-ds-base-1.3.6.8.ebuild |
39 |
rename to net-nds/389-ds-base/389-ds-base-1.3.6.8-r1.ebuild |
40 |
index 6fddd0315a5..0232cdec1d4 100644 |
41 |
--- a/net-nds/389-ds-base/389-ds-base-1.3.6.8.ebuild |
42 |
+++ b/net-nds/389-ds-base/389-ds-base-1.3.6.8-r1.ebuild |
43 |
@@ -1,4 +1,4 @@ |
44 |
-# Copyright 1999-2017 Gentoo Foundation |
45 |
+# Copyright 1999-2018 Gentoo Foundation |
46 |
# Distributed under the terms of the GNU General Public License v2 |
47 |
|
48 |
EAPI=5 |
49 |
@@ -53,6 +53,8 @@ src_prepare() { |
50 |
# as per 389 documentation, when 64bit, export USE_64 |
51 |
use amd64 && export USE_64=1 |
52 |
|
53 |
+ epatch "${FILESDIR}/389-ds-base-1.3.6-backport-invalid-password-mig.patch" |
54 |
+ |
55 |
eautoreconf |
56 |
|
57 |
append-lfs-flags |
58 |
|
59 |
diff --git a/net-nds/389-ds-base/389-ds-base-9999.ebuild b/net-nds/389-ds-base/389-ds-base-9999.ebuild |
60 |
index 463fd580d5d..046375125af 100644 |
61 |
--- a/net-nds/389-ds-base/389-ds-base-9999.ebuild |
62 |
+++ b/net-nds/389-ds-base/389-ds-base-9999.ebuild |
63 |
@@ -1,4 +1,4 @@ |
64 |
-# Copyright 1999-2017 Gentoo Foundation |
65 |
+# Copyright 1999-2018 Gentoo Foundation |
66 |
# Distributed under the terms of the GNU General Public License v2 |
67 |
|
68 |
EAPI=5 |
69 |
|
70 |
diff --git a/net-nds/389-ds-base/files/389-ds-base-1.3.6-backport-invalid-password-mig.patch b/net-nds/389-ds-base/files/389-ds-base-1.3.6-backport-invalid-password-mig.patch |
71 |
new file mode 100644 |
72 |
index 00000000000..b4ba70a2fb5 |
73 |
--- /dev/null |
74 |
+++ b/net-nds/389-ds-base/files/389-ds-base-1.3.6-backport-invalid-password-mig.patch |
75 |
@@ -0,0 +1,376 @@ |
76 |
+From cefec5714cf0fdec4aa582a5fe020ef80d6024cd Mon Sep 17 00:00:00 2001 |
77 |
+From: William Brown <firstyear@××××××.com> |
78 |
+Date: Thu, 18 Jan 2018 11:27:58 +1000 |
79 |
+Subject: [PATCH] Ticket bz1525628 1.3.6 backport - invalid password migration |
80 |
+ causes unauth bind |
81 |
+ |
82 |
+Bug Description: Slapi_ct_memcmp expects both inputs to be |
83 |
+at LEAST size n. If they are not, we only compared UP to n. |
84 |
+ |
85 |
+Invalid migrations of passwords (IE {CRYPT}XX) would create |
86 |
+a pw which is just salt and no hash. ct_memcmp would then |
87 |
+only verify the salt bits and would allow the authentication. |
88 |
+ |
89 |
+This relies on an administrative mistake both of allowing |
90 |
+password migration (nsslapd-allow-hashed-passwords) and then |
91 |
+subsequently migrating an INVALID password to the server. |
92 |
+ |
93 |
+Fix Description: slapi_ct_memcmp now access n1, n2 size |
94 |
+and will FAIL if they are not the same, but will still compare |
95 |
+n bytes, where n is the "longest" memory, to the first byte |
96 |
+of the other to prevent length disclosure of the shorter |
97 |
+value (generally the mis-migrated password) |
98 |
+ |
99 |
+https://bugzilla.redhat.com/show_bug.cgi?id=1525628 |
100 |
+ |
101 |
+Author: wibrown |
102 |
+ |
103 |
+Review by: ??? |
104 |
+--- |
105 |
+ .../bz1525628_ct_memcmp_invalid_hash_test.py | 56 ++++++++++++++++++++ |
106 |
+ ldap/servers/plugins/pwdstorage/clear_pwd.c | 4 +- |
107 |
+ ldap/servers/plugins/pwdstorage/crypt_pwd.c | 4 +- |
108 |
+ ldap/servers/plugins/pwdstorage/md5_pwd.c | 36 ++++++------- |
109 |
+ ldap/servers/plugins/pwdstorage/sha_pwd.c | 18 +++++-- |
110 |
+ ldap/servers/plugins/pwdstorage/smd5_pwd.c | 60 +++++++++++----------- |
111 |
+ ldap/servers/slapd/ch_malloc.c | 36 +++++++++++-- |
112 |
+ ldap/servers/slapd/slapi-plugin.h | 2 +- |
113 |
+ 8 files changed, 155 insertions(+), 61 deletions(-) |
114 |
+ create mode 100644 dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py |
115 |
+ |
116 |
+diff --git a/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py |
117 |
+new file mode 100644 |
118 |
+index 0000000..2f38384 |
119 |
+--- /dev/null |
120 |
++++ b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py |
121 |
+@@ -0,0 +1,56 @@ |
122 |
++# --- BEGIN COPYRIGHT BLOCK --- |
123 |
++# Copyright (C) 2018 Red Hat, Inc. |
124 |
++# All rights reserved. |
125 |
++# |
126 |
++# License: GPL (version 3 or any later version). |
127 |
++# See LICENSE for details. |
128 |
++# --- END COPYRIGHT BLOCK --- |
129 |
++# |
130 |
++ |
131 |
++import ldap |
132 |
++import pytest |
133 |
++import logging |
134 |
++from lib389.topologies import topology_st |
135 |
++from lib389._constants import PASSWORD, DEFAULT_SUFFIX |
136 |
++ |
137 |
++from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES |
138 |
++ |
139 |
++logging.getLogger(__name__).setLevel(logging.DEBUG) |
140 |
++log = logging.getLogger(__name__) |
141 |
++ |
142 |
++def test_invalid_hash_fails(topology_st): |
143 |
++ """When given a malformed hash from userpassword migration |
144 |
++ slapi_ct_memcmp would check only to the length of the shorter |
145 |
++ field. This affects some values where it would ONLY verify |
146 |
++ the salt is valid, and thus would allow any password to bind. |
147 |
++ |
148 |
++ :id: 8131c029-7147-47db-8d03-ec5db2a01cfb |
149 |
++ :setup: Standalone Instance |
150 |
++ :steps: |
151 |
++ 1. Create a user |
152 |
++ 2. Add an invalid password hash (truncated) |
153 |
++ 3. Attempt to bind |
154 |
++ :expectedresults: |
155 |
++ 1. User is added |
156 |
++ 2. Invalid pw hash is added |
157 |
++ 3. Bind fails |
158 |
++ """ |
159 |
++ log.info("Running invalid hash test") |
160 |
++ |
161 |
++ # Allow setting raw password hashes for migration. |
162 |
++ topology_st.standalone.config.set('nsslapd-allow-hashed-passwords', 'on') |
163 |
++ |
164 |
++ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) |
165 |
++ user = users.create(properties=TEST_USER_PROPERTIES) |
166 |
++ user.set('userPassword', '{CRYPT}XX') |
167 |
++ |
168 |
++ # Attempt to bind. This should fail. |
169 |
++ with pytest.raises(ldap.INVALID_CREDENTIALS): |
170 |
++ user.bind(PASSWORD) |
171 |
++ with pytest.raises(ldap.INVALID_CREDENTIALS): |
172 |
++ user.bind('XX') |
173 |
++ with pytest.raises(ldap.INVALID_CREDENTIALS): |
174 |
++ user.bind('{CRYPT}XX') |
175 |
++ |
176 |
++ log.info("PASSED") |
177 |
++ |
178 |
+diff --git a/ldap/servers/plugins/pwdstorage/clear_pwd.c b/ldap/servers/plugins/pwdstorage/clear_pwd.c |
179 |
+index b9b362d..050e60d 100644 |
180 |
+--- a/ldap/servers/plugins/pwdstorage/clear_pwd.c |
181 |
++++ b/ldap/servers/plugins/pwdstorage/clear_pwd.c |
182 |
+@@ -39,7 +39,7 @@ clear_pw_cmp( const char *userpwd, const char *dbpwd ) |
183 |
+ * However, even if the first part of userpw matches dbpwd, but len !=, we |
184 |
+ * have already failed anyawy. This prevents substring matching. |
185 |
+ */ |
186 |
+- if (slapi_ct_memcmp(userpwd, dbpwd, len_dbp) != 0) { |
187 |
++ if (slapi_ct_memcmp(userpwd, dbpwd, len_user, len_dbp) != 0) { |
188 |
+ result = 1; |
189 |
+ } |
190 |
+ } else { |
191 |
+@@ -51,7 +51,7 @@ clear_pw_cmp( const char *userpwd, const char *dbpwd ) |
192 |
+ * dbpwd to itself. We have already got result == 1 if we are here, so we are |
193 |
+ * just trying to take up time! |
194 |
+ */ |
195 |
+- if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp)) { |
196 |
++ if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp, len_dbp)) { |
197 |
+ /* Do nothing, we have the if to fix a coverity check. */ |
198 |
+ } |
199 |
+ } |
200 |
+diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c |
201 |
+index dfd5af9..5fcff13 100644 |
202 |
+--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c |
203 |
++++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c |
204 |
+@@ -56,13 +56,13 @@ crypt_close(Slapi_PBlock *pb __attribute__((unused))) |
205 |
+ int |
206 |
+ crypt_pw_cmp( const char *userpwd, const char *dbpwd ) |
207 |
+ { |
208 |
+- int rc; |
209 |
++ int32_t rc; |
210 |
+ char *cp; |
211 |
+ PR_Lock(cryptlock); |
212 |
+ /* we use salt (first 2 chars) of encoded password in call to crypt() */ |
213 |
+ cp = crypt( userpwd, dbpwd ); |
214 |
+ if (cp) { |
215 |
+- rc= slapi_ct_memcmp( dbpwd, cp, strlen(dbpwd)); |
216 |
++ rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd), strlen(cp)); |
217 |
+ } else { |
218 |
+ rc = -1; |
219 |
+ } |
220 |
+diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c |
221 |
+index b279946..2e1c472 100644 |
222 |
+--- a/ldap/servers/plugins/pwdstorage/md5_pwd.c |
223 |
++++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c |
224 |
+@@ -30,13 +30,13 @@ |
225 |
+ int |
226 |
+ md5_pw_cmp( const char *userpwd, const char *dbpwd ) |
227 |
+ { |
228 |
+- int rc=-1; |
229 |
+- char * bver; |
230 |
+- PK11Context *ctx=NULL; |
231 |
+- unsigned int outLen; |
232 |
+- unsigned char hash_out[MD5_HASH_LEN]; |
233 |
+- unsigned char b2a_out[MD5_HASH_LEN*2]; /* conservative */ |
234 |
+- SECItem binary_item; |
235 |
++ int32_t rc = -1; |
236 |
++ char *bver; |
237 |
++ PK11Context *ctx = NULL; |
238 |
++ unsigned int outLen; |
239 |
++ unsigned char hash_out[MD5_HASH_LEN]; |
240 |
++ unsigned char b2a_out[MD5_HASH_LEN * 2]; /* conservative */ |
241 |
++ SECItem binary_item; |
242 |
+ |
243 |
+ ctx = PK11_CreateDigestContext(SEC_OID_MD5); |
244 |
+ if (ctx == NULL) { |
245 |
+@@ -51,17 +51,17 @@ md5_pw_cmp( const char *userpwd, const char *dbpwd ) |
246 |
+ PK11_DigestFinal(ctx, hash_out, &outLen, sizeof hash_out); |
247 |
+ PK11_DestroyContext(ctx, 1); |
248 |
+ |
249 |
+- /* convert the binary hash to base64 */ |
250 |
+- binary_item.data = hash_out; |
251 |
+- binary_item.len = outLen; |
252 |
+- bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item); |
253 |
+- /* bver points to b2a_out upon success */ |
254 |
+- if (bver) { |
255 |
+- rc = slapi_ct_memcmp(bver,dbpwd, strlen(dbpwd)); |
256 |
+- } else { |
257 |
+- slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME, |
258 |
+- "Could not base64 encode hashed value for password compare"); |
259 |
+- } |
260 |
++ /* convert the binary hash to base64 */ |
261 |
++ binary_item.data = hash_out; |
262 |
++ binary_item.len = outLen; |
263 |
++ bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item); |
264 |
++ /* bver points to b2a_out upon success */ |
265 |
++ if (bver) { |
266 |
++ rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd), strlen(bver)); |
267 |
++ } else { |
268 |
++ slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME, |
269 |
++ "Could not base64 encode hashed value for password compare"); |
270 |
++ } |
271 |
+ loser: |
272 |
+ return rc; |
273 |
+ } |
274 |
+diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c |
275 |
+index 5f41c5b..c9db896 100644 |
276 |
+--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c |
277 |
++++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c |
278 |
+@@ -49,7 +49,7 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen ) |
279 |
+ char userhash[MAX_SHA_HASH_SIZE]; |
280 |
+ char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3]; |
281 |
+ char *dbhash = quick_dbhash; |
282 |
+- struct berval salt; |
283 |
++ struct berval salt = {0}; |
284 |
+ PRUint32 hash_len; |
285 |
+ unsigned int secOID; |
286 |
+ char *schemeName; |
287 |
+@@ -120,10 +120,20 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen ) |
288 |
+ } |
289 |
+ |
290 |
+ /* the proof is in the comparison... */ |
291 |
+- if ( hash_len >= shaLen ) { |
292 |
+- result = slapi_ct_memcmp( userhash, dbhash, shaLen ); |
293 |
++ if (hash_len >= shaLen) { |
294 |
++ /* |
295 |
++ * This say "if the hash has a salt IE >, OR if they are equal, check the hash component ONLY. |
296 |
++ * This is why we repeat shaLen twice, even though it seems odd. If you have a dbhast of ssha |
297 |
++ * it's len is 28, and the userpw is 20, but 0 - 20 is the sha, and 21-28 is the salt, which |
298 |
++ * has already been processed into userhash. |
299 |
++ * The case where dbpwd is truncated is handled above in "invalid base64" arm. |
300 |
++ */ |
301 |
++ result = slapi_ct_memcmp(userhash, dbhash, shaLen, shaLen); |
302 |
+ } else { |
303 |
+- result = slapi_ct_memcmp( userhash, dbhash + OLD_SALT_LENGTH, hash_len - OLD_SALT_LENGTH ); |
304 |
++ /* This case is for if the salt is at the START, which only applies to DS40B1 case. |
305 |
++ * May never be a valid check... |
306 |
++ */ |
307 |
++ result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, shaLen, hash_len - OLD_SALT_LENGTH); |
308 |
+ } |
309 |
+ |
310 |
+ loser: |
311 |
+diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c |
312 |
+index 2e9d195..f6b4bb4 100644 |
313 |
+--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c |
314 |
++++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c |
315 |
+@@ -52,35 +52,37 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd ) |
316 |
+ /* |
317 |
+ * Decode hash stored in database. |
318 |
+ */ |
319 |
+- hash_len = pwdstorage_base64_decode_len(dbpwd, 0); |
320 |
+- if ( hash_len >= sizeof(quick_dbhash) ) { /* get more space: */ |
321 |
+- dbhash = (char*) slapi_ch_calloc( hash_len + 1, sizeof(char) ); |
322 |
+- if ( dbhash == NULL ) goto loser; |
323 |
+- } else { |
324 |
+- memset( quick_dbhash, 0, sizeof(quick_dbhash) ); |
325 |
+- } |
326 |
+- |
327 |
+- hashresult = PL_Base64Decode( dbpwd, 0, dbhash ); |
328 |
+- if (NULL == hashresult) { |
329 |
+- slapi_log_err(SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME, |
330 |
+- "smd5_pw_cmp: userPassword \"%s\" is the wrong length " |
331 |
+- "or is not properly encoded BASE64\n", dbpwd ); |
332 |
+- goto loser; |
333 |
+- } |
334 |
+- |
335 |
+- salt.bv_val = (void*)(dbhash + MD5_LENGTH); /* salt starts after hash value */ |
336 |
+- salt.bv_len = hash_len - MD5_LENGTH; /* remaining bytes must be salt */ |
337 |
+- |
338 |
+- /* create the hash */ |
339 |
+- memset( userhash, 0, sizeof(userhash) ); |
340 |
+- PK11_DigestBegin(ctx); |
341 |
+- PK11_DigestOp(ctx, (const unsigned char *)userpwd, strlen(userpwd)); |
342 |
+- PK11_DigestOp(ctx, (unsigned char*)(salt.bv_val), salt.bv_len); |
343 |
+- PK11_DigestFinal(ctx, userhash, &outLen, sizeof userhash); |
344 |
+- PK11_DestroyContext(ctx, 1); |
345 |
+- |
346 |
+- /* Compare everything up to the salt. */ |
347 |
+- rc = slapi_ct_memcmp( userhash, dbhash, MD5_LENGTH ); |
348 |
++ hash_len = pwdstorage_base64_decode_len(dbpwd, 0); |
349 |
++ if (hash_len >= sizeof(quick_dbhash)) { /* get more space: */ |
350 |
++ dbhash = (char *)slapi_ch_calloc(hash_len + 1, sizeof(char)); |
351 |
++ if (dbhash == NULL) |
352 |
++ goto loser; |
353 |
++ } else { |
354 |
++ memset(quick_dbhash, 0, sizeof(quick_dbhash)); |
355 |
++ } |
356 |
++ |
357 |
++ hashresult = PL_Base64Decode(dbpwd, 0, dbhash); |
358 |
++ if (NULL == hashresult) { |
359 |
++ slapi_log_err(SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME, |
360 |
++ "smd5_pw_cmp: userPassword \"%s\" is the wrong length " |
361 |
++ "or is not properly encoded BASE64\n", |
362 |
++ dbpwd); |
363 |
++ goto loser; |
364 |
++ } |
365 |
++ |
366 |
++ salt.bv_val = (void *)(dbhash + MD5_LENGTH); /* salt starts after hash value */ |
367 |
++ salt.bv_len = hash_len - MD5_LENGTH; /* remaining bytes must be salt */ |
368 |
++ |
369 |
++ /* create the hash */ |
370 |
++ memset(userhash, 0, sizeof(userhash)); |
371 |
++ PK11_DigestBegin(ctx); |
372 |
++ PK11_DigestOp(ctx, (const unsigned char *)userpwd, strlen(userpwd)); |
373 |
++ PK11_DigestOp(ctx, (unsigned char *)(salt.bv_val), salt.bv_len); |
374 |
++ PK11_DigestFinal(ctx, userhash, &outLen, sizeof userhash); |
375 |
++ PK11_DestroyContext(ctx, 1); |
376 |
++ |
377 |
++ /* Compare everything up to the salt. */ |
378 |
++ rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH, MD5_LENGTH); |
379 |
+ |
380 |
+ loser: |
381 |
+ if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free_string( (char **)&dbhash ); |
382 |
+diff --git a/ldap/servers/slapd/ch_malloc.c b/ldap/servers/slapd/ch_malloc.c |
383 |
+index 52ccb64..66cb692 100644 |
384 |
+--- a/ldap/servers/slapd/ch_malloc.c |
385 |
++++ b/ldap/servers/slapd/ch_malloc.c |
386 |
+@@ -343,8 +343,8 @@ slapi_ch_smprintf(const char *fmt, ...) |
387 |
+ |
388 |
+ /* Constant time memcmp. Does not shortcircuit on failure! */ |
389 |
+ /* This relies on p1 and p2 both being size at least n! */ |
390 |
+-int |
391 |
+-slapi_ct_memcmp( const void *p1, const void *p2, size_t n) |
392 |
++int32_t |
393 |
++slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2) |
394 |
+ { |
395 |
+ int result = 0; |
396 |
+ const unsigned char *_p1 = (const unsigned char *)p1; |
397 |
+@@ -354,9 +354,35 @@ slapi_ct_memcmp( const void *p1, const void *p2, size_t n) |
398 |
+ return 2; |
399 |
+ } |
400 |
+ |
401 |
+- for (size_t i = 0; i < n; i++) { |
402 |
+- if (_p1[i] ^ _p2[i]) { |
403 |
+- result = 1; |
404 |
++ if (n1 == n2) { |
405 |
++ for (size_t i = 0; i < n1; i++) { |
406 |
++ if (_p1[i] ^ _p2[i]) { |
407 |
++ result = 1; |
408 |
++ } |
409 |
++ } |
410 |
++ } else { |
411 |
++ const unsigned char *_pa; |
412 |
++ const unsigned char *_pb; |
413 |
++ size_t nl; |
414 |
++ if (n2 > n1) { |
415 |
++ _pa = _p2; |
416 |
++ _pb = _p2; |
417 |
++ nl = n2; |
418 |
++ } else { |
419 |
++ _pa = _p1; |
420 |
++ _pb = _p1; |
421 |
++ nl = n1; |
422 |
++ } |
423 |
++ /* We already fail as n1 != n2 */ |
424 |
++ result = 3; |
425 |
++ for (size_t i = 0; i < nl; i++) { |
426 |
++ if (_pa[i] ^ _pb[i]) { |
427 |
++ /* |
428 |
++ * If we don't mutate result here, dead code elimination |
429 |
++ * we remove for loop. |
430 |
++ */ |
431 |
++ result = 4; |
432 |
++ } |
433 |
+ } |
434 |
+ } |
435 |
+ return result; |
436 |
+diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h |
437 |
+index d37bc63..2c5c4ce 100644 |
438 |
+--- a/ldap/servers/slapd/slapi-plugin.h |
439 |
++++ b/ldap/servers/slapd/slapi-plugin.h |
440 |
+@@ -5859,7 +5859,7 @@ char * slapi_ch_smprintf(const char *fmt, ...) |
441 |
+ * \param n length in bytes of the content of p1 AND p2. |
442 |
+ * \return 0 on match. 1 on non-match. 2 on presence of NULL pointer in p1 or p2. |
443 |
+ */ |
444 |
+-int slapi_ct_memcmp( const void *p1, const void *p2, size_t n); |
445 |
++int32_t slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2); |
446 |
+ |
447 |
+ /* |
448 |
+ * syntax plugin routines |
449 |
+-- |
450 |
+1.8.3.1 |
451 |
+ |