Skip to content

Commit ec7011c

Browse files
authored
Merge pull request #9010 from nadavMiz/supplemental_groups_concurrency
NC | supplemental groups - getpwuid concurrency issue
2 parents 07940b2 + 84a39cf commit ec7011c

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

src/native/fs/fs_napi.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ typedef std::map<std::string, std::string> XattrMap;
168168
const char* gpfs_dl_path = std::getenv("GPFS_DL_PATH");
169169

170170
int gpfs_lib_file_exists = -1;
171-
static long PASSWD_BUF_SIZE = -1;
172171

173172
static int (*dlsym_gpfs_fcntl)(gpfs_file_t file, void* arg) = 0;
174173

@@ -1410,12 +1409,13 @@ struct GetPwName : public FSWorker
14101409
}
14111410
virtual void Work()
14121411
{
1413-
_buf.reset(new char[PASSWD_BUF_SIZE]);
1412+
const long passwd_buf_size = ThreadScope::get_passwd_buf_size();
1413+
_buf.reset(new char[passwd_buf_size]);
14141414
if (!_buf) {
14151415
SetSyscallError();
14161416
return;
14171417
}
1418-
int rc = getpwnam_r(_user.c_str(), &_pwd, _buf.get(), PASSWD_BUF_SIZE, &_getpwnam_res);
1418+
int rc = getpwnam_r(_user.c_str(), &_pwd, _buf.get(), passwd_buf_size, &_getpwnam_res);
14191419
if (rc != 0) {
14201420
SetSyscallError();
14211421
return;
@@ -2415,11 +2415,7 @@ fs_napi(Napi::Env env, Napi::Object exports)
24152415
exports_fs["DT_DIR"] = Napi::Number::New(env, DT_DIR);
24162416
exports_fs["DT_LNK"] = Napi::Number::New(env, DT_LNK);
24172417
exports_fs["PLATFORM_IOV_MAX"] = Napi::Number::New(env, IOV_MAX);
2418-
long passwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2419-
if (passwd_bufsize == -1) {
2420-
passwd_bufsize = 16384;
2421-
}
2422-
PASSWD_BUF_SIZE = passwd_bufsize;
2418+
ThreadScope::init_passwd_buf_size();
24232419

24242420

24252421
#ifdef O_DIRECT

src/native/util/os.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ class ThreadScope
4141
change_user();
4242
}
4343

44+
static void init_passwd_buf_size()
45+
{
46+
long passwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
47+
if (passwd_bufsize == -1) {
48+
passwd_bufsize = 16384;
49+
}
50+
passwd_buf_size = passwd_bufsize;
51+
}
52+
53+
static long get_passwd_buf_size()
54+
{
55+
return passwd_buf_size;
56+
}
57+
4458
int add_thread_capabilities();
4559

4660
const static uid_t orig_uid;
@@ -55,6 +69,8 @@ class ThreadScope
5569
uid_t _uid;
5670
gid_t _gid;
5771
std::vector<gid_t> _groups;
72+
73+
static long passwd_buf_size;
5874
};
5975

6076
} // namespace noobaa

src/native/util/os_darwin.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,19 @@ get_current_uid()
4343
const uid_t ThreadScope::orig_uid = getuid();
4444
const gid_t ThreadScope::orig_gid = getgid();
4545
const std::vector<gid_t> ThreadScope::orig_groups = get_process_groups();
46+
long ThreadScope::passwd_buf_size = -1;
4647

4748
static int
4849
get_supplemental_groups_by_uid(uid_t uid, std::vector<gid_t>& groups)
4950
{
50-
// getpwuid will only indicate if an error happened by setting errno. set it to 0, so will know if there is a change
51-
errno = 0;
52-
struct passwd* pw = getpwuid(uid);
51+
const long passwd_buf_size = ThreadScope::get_passwd_buf_size();
52+
std::unique_ptr<char[]> buf(new char[passwd_buf_size]);
53+
struct passwd pwd;
54+
struct passwd *pw = NULL;
55+
56+
const int res = getpwuid_r(uid, &pwd, buf.get(), passwd_buf_size, &pw);
5357
if (pw == NULL) {
54-
if (errno == 0) {
58+
if (res == 0) {
5559
// LOG("get_supplemental_groups_by_uid: no record for uid " << uid);
5660
} else {
5761
LOG("WARNING: get_supplemental_groups_by_uid: getpwuid failed: " << strerror(errno));

src/native/util/os_linux.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,21 @@ get_current_uid()
2727

2828
const uid_t ThreadScope::orig_uid = getuid();
2929
const gid_t ThreadScope::orig_gid = getgid();
30+
long ThreadScope::passwd_buf_size = -1;
3031

3132
const std::vector<gid_t> ThreadScope::orig_groups = get_process_groups();
3233

3334
static int
3435
get_supplemental_groups_by_uid(uid_t uid, std::vector<gid_t>& groups)
3536
{
36-
// getpwuid will only indicate if an error happened by setting errno. set it to 0, so will know if there is a change
37-
errno = 0;
38-
struct passwd* pw = getpwuid(uid);
37+
const long passwd_buf_size = ThreadScope::get_passwd_buf_size();
38+
std::unique_ptr<char[]> buf(new char[passwd_buf_size]);
39+
struct passwd pwd;
40+
struct passwd *pw = NULL;
41+
42+
const int res = getpwuid_r(uid, &pwd, buf.get(), passwd_buf_size, &pw);
3943
if (pw == NULL) {
40-
if (errno == 0) {
44+
if (res == 0) {
4145
// LOG("get_supplemental_groups_by_uid: no record for uid " << uid);
4246
} else {
4347
LOG("WARNING: get_supplemental_groups_by_uid: getpwuid failed: " << strerror(errno));

0 commit comments

Comments
 (0)