I have a problem with a piece of Linux code (written in C++) that does something like this:
- Create a new directory with mkdir("xyz",0755) which succeeds (return code is 0).
- Tries to open/create a new file in the justly created directory.
- Fails because the permissions on the new directory is actually 0600 and NOT 0755 as requested.
The code looks like this and checks that the path prefix "/tmp/slim" exists before coming to this part:
int somefunc(const string& path)
{
if ( mkdir( path.c_str(), 0755 ) == 0 ) {
// (*) if (!access( path.c_str(), F_OK | R_OK | W_OK | X_OK ) == 0 )
// (*) chmod( path.c_str(), 0755);
string pidinfo = to_string( getpid() ) + "\n";
string pidinfofile = path + "/pid";
int fd = open( pidinfofile.c_str(), O_RDWR | O_CREAT, S_IWUSR | S_IRUSR );
if ( fd == -1 )
return 0;
ssize_t written = write( fd, text.c_str(), text.size() );
// ... do more stuff
}
}
As this snippet of a strace (no lines missing/redacted) shows, the openat() fails even though the mkdir() returned 0.
13661 16:32:22.068465 mkdir("/tmp/slim/testsock", 0755) = 0
13661 16:32:22.068720 getpid() = 13661
13661 16:32:22.068829 openat(AT_FDCWD, "/tmp/slim/testsock/pid", O_RDWR|O_CREAT, 0600) = -1 EACCES (Permission denied)
The result of running getfacl looks like this:
[localhost]$ getfacl /tmp/slim/
getfacl: Removing leading '/' from absolute path names
# file: tmp/slim/
# owner: stk
# group: stk
user::rwx
group::r-x
other::r-x
How can the the mkdir() return 0 but create a directory with permissions that differ from the specified? It's not a umask thing, I've tried setting umask to 0 before creating the directory without any effect. If the two commented lines marked with (*) is enabled/uncommented, things work as they should - but I don't like that sort of symptom treatment that skirts the real problem. There's got to be a reasonable explanation for this seemingly weird behavior.
Part of the story is that this works in an application with multiple threads. Each thread performs the code above (which is a smallish, thread safe function), and most threads succeed, but there's always 1 or 2 (out of 5-10) that fails as described.