From a52379db8745e23647f776f78ee2b0d85cc223f2 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 29 Sep 2018 22:35:32 +0200 Subject: [PATCH] Wayland: Use memfd_create() and seals if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the compositor to avoid having to setup and teardown a SIGBUS signal handler whenever it needs to read from this surface, as it knows we won’t be able to shrink the file and so doesn’t have to protect against that. This codepath will only be used on Linux ≥ 3.17 with glibc ≥ 2.27, and possibly other kernels and libc. The former code will continue to be used as a fallback, either if memfd_create() fails or if it isn’t available. --- CMakeLists.txt | 2 ++ src/glfw_config.h.in | 2 ++ src/wl_window.c | 42 ++++++++++++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f9dbcf7f..a0517db53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,9 @@ if (_GLFW_WAYLAND) list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") include(CheckIncludeFiles) + include(CheckFunctionExists) check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H) + check_function_exists(memfd_create HAVE_MEMFD_CREATE) if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")) find_package(EpollShim) diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index 0b47945c0..381ad2885 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -57,4 +57,6 @@ // Define this to 1 if xkbcommon supports the compose key #cmakedefine HAVE_XKBCOMMON_COMPOSE_H +// Define this to 1 if the libc supports memfd_create() +#cmakedefine HAVE_MEMFD_CREATE diff --git a/src/wl_window.c b/src/wl_window.c index b23dc7460..ef45baef5 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -144,23 +144,37 @@ static int createAnonymousFile(off_t size) int fd; int ret; - path = getenv("XDG_RUNTIME_DIR"); - if (!path) +#ifdef HAVE_MEMFD_CREATE + fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (fd >= 0) { - errno = ENOENT; - return -1; + // We can add this seal before calling posix_fallocate(), as the file + // is currently zero-sized anyway. + // + // There is also no need to check for the return value, we couldn’t do + // anything with it anyway. + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL); + } + else +#endif + { + path = getenv("XDG_RUNTIME_DIR"); + if (!path) + { + errno = ENOENT; + return -1; + } + + name = calloc(strlen(path) + sizeof(template), 1); + strcpy(name, path); + strcat(name, template); + + fd = createTmpfileCloexec(name); + free(name); + if (fd < 0) + return -1; } - name = calloc(strlen(path) + sizeof(template), 1); - strcpy(name, path); - strcat(name, template); - - fd = createTmpfileCloexec(name); - - free(name); - - if (fd < 0) - return -1; ret = posix_fallocate(fd, 0, size); if (ret != 0) {