crypt()不是线程安全的
crypt()通常不是线程安全的,但这个问题不容易暴露,和平台也有一定关系,所以也没引起重视。
最近在AIX5.2遇到了问题,查了很就才查出是crypt这个罪魁祸首。写了段简单的代码来验证这个情况。
测试环境:
$ uname -a
AIX P270 2 5 0005A9DC4C00
测试1:
testcrypt.c:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_proc( void *arg )
{
static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static int count=0;
int id,i;
const char *key = "teststring";
char *passwd = NULL;
id = (int)arg;
for( i=0;i<5;i++ )
{
pthread_mutex_lock(&lock);
passwd=(char *)crypt(key, "crypt_salt");
printf( "Thread(%d),count=%02d: crypt( key=/"%s/" ) = /"%s/"/n", id,count++, key, passwd );
pthread_mutex_unlock(&lock);
usleep(10000);
}
}
int main (int argc, char *argv[])
{
pthread_t thr[3];
int i;
for(i=0;i<3;i++)
pthread_create(&thr[i],NULL,thread_proc,(void *)i);
for(i=0;i<3;i++)
pthread_join(thr[i],NULL);
return 0;
}
输出结果:
$ ./testcrypt
Thread(0),count=00: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=01: crypt( key="teststring" ) = "crmfN8KIyUzlw"
Thread(2),count=02: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=03: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=04: crypt( key="teststring" ) = "crUQZ0p1aAxhk"
Thread(2),count=05: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=06: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=07: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=08: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=09: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=10: crypt( key="teststring" ) = "crA80NREnJc0o"
Thread(2),count=11: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=12: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=13: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=14: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
测试2:
修改后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_proc( void *arg )
{
static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static int count=0;
int id,i;
const char *key = "teststring";
char *passwd = NULL;
id = (int)arg;
for( i=0;i<5;i++ )
{
pthread_mutex_lock(&lock);
passwd=(char *)crypt(key, "crypt_salt");
printf( "Thread(%d),count=%02d: crypt( key=/"%s/" ) = /"%s/"/n", id,count++, key, passwd );
pthread_mutex_unlock(&lock);
usleep(10000);
}
}
int main (int argc, char *argv[])
{
pthread_t thr[3];
int i;
for(i=0;i<3;i++)
pthread_create(&thr[i],NULL,thread_proc,(void *)i);
for(i=0;i<3;i++)
pthread_join(thr[i],NULL);
return 0;
}
输出结果:
$ ./testcrypt
Thread(0),count=00: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=01: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=02: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=03: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=04: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=05: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=06: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=07: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=08: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(0),count=09: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(1),count=10: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=11: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=12: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=13: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"
Thread(2),count=14: crypt( key="teststring" ) = "cr/mm2Fx7dCAM"