From 3d227536f7d53a3c3d58c066492eb8a5db834089 Mon Sep 17 00:00:00 2001 From: William Brown Date: Nov 03 2016 19:04:59 +0000 Subject: Ticket bz1358565 - clear and unsalted password types are vulnerable to timing attack Bug Description: Clear and unsalted password types were vulnerable to a timing attack. This is due to the use of memcmp and strcmp in their comparison. Fix Description: Add a constant time memcmp function, that does not shortcircuit. Change all password comparison to use the constant time check. For the clear scheme, alter the way we do the check to prevent length disclosure timing attacks. This resolves CVE-2016-5405 https://bugzilla.redhat.com/show_bug.cgi?id=1358565 https://access.redhat.com/security/cve/CVE-2016-5405 Author: wibrown Review by: nhosoi (Thanks!) (cherry picked from commit 9dcaa4a0c866d8696e0a2616ccf962af2833f0b8) (cherry picked from commit 762219a35005914c6c088d915ac9346ce7e28512) --- diff --git a/ldap/servers/slapd/ch_malloc.c b/ldap/servers/slapd/ch_malloc.c index 705ea86..515e746 100644 --- a/ldap/servers/slapd/ch_malloc.c +++ b/ldap/servers/slapd/ch_malloc.c @@ -119,6 +119,7 @@ slapi_ch_malloc( size, oserr, slapd_system_strerror( oserr ), oom_advice ); exit( 1 ); } + if(!counters_created) { create_counters(); @@ -128,6 +129,33 @@ slapi_ch_malloc( PR_INCREMENT_COUNTER(slapi_ch_counter_created); PR_INCREMENT_COUNTER(slapi_ch_counter_exist); + /* So long as this happens once, we are happy, put it in ch_malloc. */ + create_oom_buffer(); + + return( newmem ); +} + +/* See slapi-plugin.h */ +char * +slapi_ch_memalign(size_t size, size_t alignment) +{ + char *newmem; + + if (size <= 0) { + log_negative_alloc_msg( "memalign", "bytes", size ); + return 0; + } + + if ( posix_memalign((void **)&newmem, alignment, size) != 0 ) { + int oserr = errno; + + oom_occurred(); + slapi_log_err(SLAPI_LOG_ERR, SLAPD_MODULE, + "malloc of %lu bytes failed; OS error %d (%s)%s\n", + size, oserr, slapd_system_strerror( oserr ), oom_advice ); + exit( 1 ); + } + return( newmem ); } @@ -374,13 +402,12 @@ slapi_ct_memcmp( const void *p1, const void *p2, size_t n) int result = 0; const unsigned char *_p1 = (const unsigned char *)p1; const unsigned char *_p2 = (const unsigned char *)p2; - size_t i; if (_p1 == NULL || _p2 == NULL) { return 2; } - for (i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { if (_p1[i] ^ _p2[i]) { result = 1; }