Fixed race condition in dirname and basename call

This commit is contained in:
Takeshi Nakatani 2022-07-24 03:11:18 +00:00 committed by Andrew Gaul
parent e0655008b3
commit 404c284440
3 changed files with 77 additions and 0 deletions

View File

@ -4529,6 +4529,14 @@ int main(int argc, char* argv[])
exit(EXIT_FAILURE);
}
// mutex for basename/dirname
if(!init_basename_lock()){
S3FS_PRN_EXIT("could not initialize mutex for basename/dirname.");
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
exit(EXIT_FAILURE);
}
// init curl (without mime types)
//
// [NOTE]
@ -4549,6 +4557,7 @@ int main(int argc, char* argv[])
S3FS_PRN_EXIT("Could not initiate curl library.");
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4563,6 +4572,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4579,6 +4589,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
if(!S3fsCurl::FinalCheckSse()){
@ -4586,6 +4597,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4605,6 +4617,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4619,6 +4632,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
}
@ -4629,6 +4643,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4638,6 +4653,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4681,6 +4697,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(exitcode);
}
@ -4695,6 +4712,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4704,6 +4722,7 @@ int main(int argc, char* argv[])
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
exit(EXIT_FAILURE);
}
@ -4764,6 +4783,7 @@ int main(int argc, char* argv[])
}
s3fs_destroy_global_ssl();
destroy_parser_xml_lock();
destroy_basename_lock();
// cleanup xml2
xmlCleanupParser();

View File

@ -37,6 +37,7 @@
#include "s3fs_util.h"
#include "string_util.h"
#include "s3fs_help.h"
#include "autolock.h"
//-------------------------------------------------------------------
// Global variables
@ -170,8 +171,60 @@ int is_uid_include_group(uid_t uid, gid_t gid)
//-------------------------------------------------------------------
// Utility for file and directory
//-------------------------------------------------------------------
// [NOTE]
// basename/dirname returns a static variable pointer as the return value.
// Normally this shouldn't be a problem, but in macos10 we found a case
// where dirname didn't receive its return value correctly due to thread
// conflicts.
// To avoid this, exclusive control is performed by mutex.
//
static pthread_mutex_t* pbasename_lock = NULL;
bool init_basename_lock()
{
if(pbasename_lock){
S3FS_PRN_ERR("already initialized mutex for posix dirname/basename function.");
return false;
}
pbasename_lock = new pthread_mutex_t;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(pbasename_lock, &attr))){
S3FS_PRN_ERR("failed to init pbasename_lock: %d.", result);
delete pbasename_lock;
pbasename_lock = NULL;
return false;
}
return true;
}
bool destroy_basename_lock()
{
if(!pbasename_lock){
S3FS_PRN_ERR("the mutex for posix dirname/basename function is not initialized.");
return false;
}
int result;
if(0 != (result = pthread_mutex_destroy(pbasename_lock))){
S3FS_PRN_ERR("failed to destroy pbasename_lock: %d", result);
return false;
}
delete pbasename_lock;
pbasename_lock = NULL;
return true;
}
std::string mydirname(const std::string& path)
{
AutoLock auto_lock(pbasename_lock);
return std::string(dirname(const_cast<char*>(path.c_str())));
}
@ -187,6 +240,8 @@ std::string mydirname(const char* path)
std::string mybasename(const std::string& path)
{
AutoLock auto_lock(pbasename_lock);
return std::string(basename(const_cast<char*>(path.c_str())));
}

View File

@ -40,6 +40,8 @@ void init_sysconf_vars();
std::string get_username(uid_t uid);
int is_uid_include_group(uid_t uid, gid_t gid);
bool init_basename_lock();
bool destroy_basename_lock();
std::string mydirname(const char* path);
std::string mydirname(const std::string& path);
std::string mybasename(const char* path);