From 9a4d8f356782d5fcf0120fe0d98d55e8d9be39fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 11 Sep 2018 23:13:37 +0200 Subject: [PATCH] Make use of getgrnam() thread-safe getgrnam is not thread-safe on Linux (but is on macOS). To ensure we don't call it from two threads at the same time we move its use inside a lambda that initializes a local static. This is fine, as we don't expect the 'nogroup' gid to change. --- sparsebundlefs.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sparsebundlefs.cpp b/sparsebundlefs.cpp index ebe7948..ac22c66 100644 --- a/sparsebundlefs.cpp +++ b/sparsebundlefs.cpp @@ -114,16 +114,20 @@ static int sparsebundle_getattr(const char *path, struct stat *stbuf) } else return -ENOENT; - // Reflect user ID of the user who mounted the file system, - // but prefer 'nogroup' for the group, since the group has - // no effect on who can access the mount. + // Reflect user ID of the user who mounted the file system stbuf->st_uid = getuid(); - if (group *nogroup = getgrnam("nogroup")) - stbuf->st_gid = nogroup->gr_gid; - else if (group *nobody = getgrnam("nobody")) - stbuf->st_gid = nobody->gr_gid; - else - stbuf->st_gid = getgid(); + + static gid_t gid = []() { + // But prefer 'nogroup' for the group, since the group + // has no actual effect on who can access the mount. + if (group *nogroup = getgrnam("nogroup")) + return nogroup->gr_gid; + if (group *nobody = getgrnam("nobody")) + return nobody->gr_gid; + // Fall back to the mounting user + return getgid(); + }(); + stbuf->st_gid = gid; // Once allow_other or allow_root is added into the mix we // want the permissions to also reflect the the situation.