[weston,1/8] Use anonymous shared memory for tempfiles

Submitted by Greg V on Dec. 17, 2017, 7:04 p.m.

Details

Message ID 20171217190442.29265-2-greg@unrelenting.technology
State New
Headers show
Series "Portability patches" ( rev: 1 ) in Wayland

Not browsing as part of any series.

Commit Message

Greg V Dec. 17, 2017, 7:04 p.m.
SHM_ANON on FreeBSD, memfd on recent Linux.

- avoids usage of posix_fallocate on Copy-on-Write filesystems like ZFS
  when XDG_RUNTIME_DIR is something like ~/.tmp instead of a tmpfs
  (FreeBSD 12 does not even allow it on ZFS anymore)
- avoids touching the filesystem, which increases sandboxing potential
---
 configure.ac              |  2 +-
 shared/os-compatibility.c | 22 ++++++++++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/configure.ac b/configure.ac
index d1b5f471..253f7e73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,7 +103,7 @@  AC_CHECK_DECL(TFD_CLOEXEC,[],
 AC_CHECK_DECL(CLOCK_MONOTONIC,[],
 	      [AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile weston")],
 	      [[#include <time.h>]])
-AC_CHECK_HEADERS([execinfo.h])
+AC_CHECK_HEADERS([execinfo.h linux/memfd.h])
 
 AC_CHECK_FUNCS([mkostemp strchrnul initgroups posix_fallocate])
 
diff --git a/shared/os-compatibility.c b/shared/os-compatibility.c
index e19fb61b..f55d3070 100644
--- a/shared/os-compatibility.c
+++ b/shared/os-compatibility.c
@@ -25,6 +25,13 @@ 
 
 #include "config.h"
 
+#ifdef __FreeBSD__
+#include <sys/mman.h>
+#elif HAVE_LINUX_MEMFD_H
+#define _GNU_SOURCE
+#include <sys/syscall.h>
+#include <linux/memfd.h>
+#endif
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <unistd.h>
@@ -107,12 +114,15 @@  os_epoll_create_cloexec(void)
 	return set_cloexec_or_close(fd);
 }
 
+#ifndef __FreeBSD__
 static int
 create_tmpfile_cloexec(char *tmpname)
 {
 	int fd;
 
-#ifdef HAVE_MKOSTEMP
+#ifdef HAVE_LINUX_MEMFD_H
+	fd = syscall(SYS_memfd_create, tmpname, MFD_CLOEXEC);
+#elif HAVE_MKOSTEMP
 	fd = mkostemp(tmpname, O_CLOEXEC);
 	if (fd >= 0)
 		unlink(tmpname);
@@ -126,6 +136,7 @@  create_tmpfile_cloexec(char *tmpname)
 
 	return fd;
 }
+#endif
 
 /*
  * Create a new, unique, anonymous file of the given size, and
@@ -151,11 +162,13 @@  create_tmpfile_cloexec(char *tmpname)
 int
 os_create_anonymous_file(off_t size)
 {
+	int fd, ret;
+#ifdef __FreeBSD__
+	fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0600); // shm_open is always CLOEXEC
+#else
 	static const char template[] = "/weston-shared-XXXXXX";
 	const char *path;
 	char *name;
-	int fd;
-	int ret;
 
 	path = getenv("XDG_RUNTIME_DIR");
 	if (!path) {
@@ -173,11 +186,12 @@  os_create_anonymous_file(off_t size)
 	fd = create_tmpfile_cloexec(name);
 
 	free(name);
+#endif
 
 	if (fd < 0)
 		return -1;
 
-#ifdef HAVE_POSIX_FALLOCATE
+#if defined(HAVE_POSIX_FALLOCATE) && !defined(__FreeBSD__)
 	do {
 		ret = posix_fallocate(fd, 0, size);
 	} while (ret == EINTR);