Skip to content

Commit

Permalink
9pfs: fix qemu_mknodat(S_IFSOCK) on macOS
Browse files Browse the repository at this point in the history
mknod() on macOS does not support creating sockets, so divert to
call sequence socket(), bind() and fchmodat() respectively if S_IFSOCK
was passed with mode argument.

Link: https://lore.kernel.org/qemu-devel/17933734.zYzKuhC07K@silver/
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <2e7b5ecd7a6d83a538db4e8a22d8fb03e9e0f06e.1651228001.git.qemu_oss@crudebyte.com>
[C.S. - Use AT_SYMLINK_NOFOLLOW instead of AT_SYMLINK_NOFOLLOW_ANY. ]
Link: https://lore.kernel.org/qemu-devel/3704033.BMyLRrx2Jx@silver/
  • Loading branch information
cschoenebeck committed May 1, 2022
1 parent 096af17 commit 055ab89
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion hw/9pfs/9p-util-darwin.c
Expand Up @@ -74,6 +74,42 @@ int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
*/
#if defined CONFIG_PTHREAD_FCHDIR_NP

static int create_socket_file_at_cwd(const char *filename, mode_t mode) {
int fd, err;
struct sockaddr_un addr = {
.sun_family = AF_UNIX
};

err = snprintf(addr.sun_path, sizeof(addr.sun_path), "./%s", filename);
if (err < 0 || err >= sizeof(addr.sun_path)) {
errno = ENAMETOOLONG;
return -1;
}
fd = socket(PF_UNIX, SOCK_DGRAM, 0);
if (fd == -1) {
return fd;
}
err = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
if (err == -1) {
goto out;
}
/*
* FIXME: Should rather be using descriptor-based fchmod() on the
* socket file descriptor above (preferably before bind() call),
* instead of path-based fchmodat(), to prevent concurrent transient
* state issues between creating the named FIFO file at bind() and
* delayed adjustment of permissions at fchmodat(). However currently
* macOS (12.x) does not support such operations on socket file
* descriptors yet.
*
* Filed report with Apple: FB9997731
*/
err = fchmodat(AT_FDCWD, filename, mode, AT_SYMLINK_NOFOLLOW);
out:
close_preserve_errno(fd);
return err;
}

int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
int preserved_errno, err;
Expand All @@ -93,7 +129,11 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
if (pthread_fchdir_np(dirfd) < 0) {
return -1;
}
err = mknod(filename, mode, dev);
if (S_ISSOCK(mode)) {
err = create_socket_file_at_cwd(filename, mode);
} else {
err = mknod(filename, mode, dev);
}
preserved_errno = errno;
/* Stop using the thread-local cwd */
pthread_fchdir_np(-1);
Expand Down

0 comments on commit 055ab89

Please sign in to comment.