-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Function dict_lookup is not thread safety, but its called from multiple threads.
Function operate on global object dict_signingtable.
pointer to the allocated memory is returned to the thread, while other thread can reallocate memory or strncpy new data.
As a result I can find in logs:
load_pem_cert: BIO_read_filename() failed
error: ctxdata_setup: loading certificate failed
callback_header: ctxdata_setup() failed: rc=3, headerf=, headerv=, file=X-Signer
probability of error depend on the number of threads. In single thread - there is no errors, 400+ threads >= one error /per second.
Enviromement:
gentoo,
postfix with 1024 smtpd workers,
dev-db/tinycdb-0.77-r2
working workaround: ensure single thread access to the method.
const char * res;
pthread_mutex_lock(&mutCdb);
res = dict_lookup_internal(dict,key);
int currentSize = strlen(res) + 1;
if ( currentSize > buffSize) {
logmsg(LOG_ERR, "DICT LOOKUP VALUE TOO LONG (%d). must be < %d",currentSize,buffSize );
pthread_mutex_unlock(&mutCdb);
exit(EX_SOFTWARE);
}
strcpy(buffer,res);
pthread_mutex_unlock(&mutCdb);
return buffer;
}
It is enough to look at code of original dict_lookup - to see that function returns pointer to allocated memory, while multiple thread can operate on the SAME pointer (ie strncpy) , even more - reallocate it. Calling function can see different string in time, it could be also free()-zed memory.
Based on the returned string - BIO is trying to open cert or key file.
Also it causes memory leak,
More details in direct email On 7/12/2021 12:11 PM,