On 09. 11. 18 21:33, Jameson Nash wrote: > # get a handle to a directory that no other user can access: > d = mkdtemp(0600) > d_ = opendir(d) > assert(owner(d_) == getpid() && group(d_) == 0 && mode(d_) == 0600) > rmdir(d)
I have tried to do quick'n'dirty implementation of this (attached). However, it turns out that moving to the deleted directory fails with "No such file or directory" error :( In the original PR, there is a similar suggestion that involves that involves forking a new process to create the socket, which I did not have the courage to test -- althoug I suspect similar issues as those encountered above. The original point of this discussion was to query how much is the API set in stone, seeing that on most UNIXes the uv_pipe_chmod is doomed to have race condition in the current state. Could (for example) the function be defined as working only before the socket is bound? Or could it be stated as *setting* (instead of adjusting) the mode, in which cases the `stat` call before could be dropped? In essence what I'm asking is how large of a change is acceptable here :) Jan -- Jan Staněk Associate Software Engineer, Core Services Red Hat Czech [email protected] IM: jstanek -- You received this message because you are subscribed to the Google Groups "libuv" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/libuv. For more options, visit https://groups.google.com/d/optout.
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
const char SOCK_PATH[] = "/tmp/test-socket";
int sock_chmod(const char *path, const mode_t mode)
{
const char sock_relpath[] = "at-socket";
char tmpdir[] = "/tmp/sock-nursery-XXXXXX";
int dirfd = 0;
int ec = 0;
// open a temporary directory
if (mkdtemp(tmpdir) == 0) {
return errno;
}
dirfd = open(tmpdir, O_DIRECTORY | O_RDONLY);
if (dirfd < 0) {
perror("open");
return errno;
}
ec = rmdir(tmpdir);
if (ec != 0) {
perror("rmdir");
return errno;
}
ec = renameat(AT_FDCWD, path, dirfd, sock_relpath);
if (ec != 0) {
perror("renameat in");
return errno;
}
ec = fchmodat(dirfd, sock_relpath, mode, 0);
if (ec != 0) {
perror("fchmodat");
return errno;
}
ec = renameat(dirfd, sock_relpath, AT_FDCWD, path);
if (ec != 0) {
perror("renameat out");
return errno;
}
return 0;
}
int main()
{
struct sockaddr_un binding = {AF_UNIX, {0}};
struct stat buf = {0};
int ec = 0, sd = -1;
unlink(SOCK_PATH);
memccpy(binding.sun_path, SOCK_PATH, '\0', sizeof(binding.sun_path));
sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd < 0) {
perror("socket");
return EXIT_FAILURE;
}
ec = bind(sd, (struct sockaddr *)&binding, sizeof(binding));
if (ec != 0) {
perror("bind");
return EXIT_FAILURE;
}
ec = stat(SOCK_PATH, &buf);
if (ec != 0) {
perror("stat orig");
return EXIT_FAILURE;
}
printf("Orig mode: %#o\n", buf.st_mode & 0777);
ec = sock_chmod(SOCK_PATH, 0777);
if (ec != 0) {
errno = ec;
perror("sock_chmod");
return EXIT_FAILURE;
}
ec = stat(SOCK_PATH, &buf);
if (ec != 0) {
perror("stat dest");
return EXIT_FAILURE;
}
printf("Dest mode: %#o\n", buf.st_mode & 0777);
assert((buf.st_mode & 0777) == 0777);
unlink(SOCK_PATH);
return EXIT_SUCCESS;
}
signature.asc
Description: OpenPGP digital signature
