Re: [PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-10-26 Thread Simon Ser
Bump.
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-09-23 Thread Simon Ser
Hi all,

Any news about this?

Thanks,

---
Simon Ser
https://emersion.fr

On Wednesday, August 15, 2018 4:14 PM, Simon Ser  wrote:
> On Linux, try using memfd_create and file sealing. Fallback to
> shm_open on old kernels.
>
> On FreeBSD, use shm_open with SHM_ANON.
>
> Otherwise, use shm_open with a random name, making sure the name
> isn't already taken.
>
> Signed-off-by: Simon Ser cont...@emersion.fr
>
> Makefile.am | 2 +-
> configure.ac | 4 +-
> cursor/os-compatibility.c | 172 ++
> 3 files changed, 86 insertions(+), 92 deletions(-)
>
> diff --git a/Makefile.am b/Makefile.am
> index 697c517..c612672 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -136,7 +136,7 @@ libwayland_cursor_la_SOURCES = \
> cursor/cursor-data.h \
> cursor/xcursor.c \
> cursor/xcursor.h
> -libwayland_cursor_la_LIBADD = libwayland-client.la
> +libwayland_cursor_la_LIBADD = libwayland-client.la -lrt
>
> pkgconfig_DATA += cursor/wayland-cursor.pc
>
> diff --git a/configure.ac b/configure.ac
> index 9419ae3..d59c61d 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -62,8 +62,8 @@ if test "x$GCC" = "xyes"; then
> fi
> AC_SUBST(GCC_CFLAGS)
>
> -AC_CHECK_HEADERS([sys/prctl.h])
> -AC_CHECK_FUNCS([accept4 mkostemp posix_fallocate prctl])
> +AC_CHECK_HEADERS([sys/prctl.h linux/memfd.h])
> +AC_CHECK_FUNCS([accept4 prctl])
>
> AC_ARG_ENABLE([libraries],
> [AC_HELP_STRING([--disable-libraries],
> diff --git a/cursor/os-compatibility.c b/cursor/os-compatibility.c
> index e972d21..96649e3 100644
> --- a/cursor/os-compatibility.c
> +++ b/cursor/os-compatibility.c
> @@ -25,124 +25,118 @@
>
> #define _GNU_SOURCE
>
> -#include 
> -#include 
> -#include 
> #include 
> -#include 
> +#include 
> #include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
>
> -
>
> +#ifdef HAVE_LINUX_MEMFD_H
> +#include 
> +#endif
>
> #include "config.h"
> #include "os-compatibility.h"
>
> -#ifndef HAVE_MKOSTEMP
> +static void
> +randname(char *buf) {
>
> -   struct timespec ts;
>
> -   long r;
>
> -   int i;
>
> -
> -   clock_gettime(CLOCK_REALTIME, );
>
> -   r = ts.tv_nsec;
>
> -   for (i = 0; i < 6; ++i) {
>
> - buf[i] = 'A'+(r&15)+(r&16)*2;
>
>
> - r >>= 5;
>
>
> -   }
> +}
>
> -
>
> static int
> -set_cloexec_or_close(int fd)
> +anonymous_shm_open(off_t size)
> {
>
> -   long flags;
> -
> -   if (fd == -1)
> - return -1;
>
>
>
> -   char name[] = "/wayland-cursor-XX";
> -   int fd, retries = 100;
>
> -   flags = fcntl(fd, F_GETFD);
> -   if (flags == -1)
> - goto err;
>
>
>
> -   do {
> - randname(name + strlen(name) - 6);
>
>
>
> -   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
> - goto err;
>
>
>
> - --retries;
>
>
> - fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0600);
>
>
> - if (fd >= 0) {
>
>
> - shm_unlink(name);
>
>
> - return fd;
>
>
> - }
>
>
> -   } while (retries > 0 && errno == EEXIST);
>
>
> -   return fd;
> -
>
> -err:
>
> -   close(fd);
> return -1;
> }
>
>
> -
>
> +static int
> +seal_or_close(int fd) {
> +#if defined(F_ADD_SEALS) && defined(F_SEAL_SHRINK)
>
> -   if (fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK) == -1) {
> - close(fd);
>
>
> - return -1;
>
>
> -   }
> #endif
>
> -   return 0;
> +}
>
> -
>
> static int
> -create_tmpfile_cloexec(char *tmpname)
> +create_anonymous_file(off_t size)
> {
>
> -   int fd;
>
> -   int fd, flags;
>
> -#ifdef HAVE_MKOSTEMP
>
>
> -   fd = mkostemp(tmpname, O_CLOEXEC);
>
> -   if (fd >= 0)
>
> - unlink(tmpname);
>
>
>
> -#else
>
> -   fd = mkstemp(tmpname);
> +#if defined(__NR_memfd_create) && defined(MFD_CLOEXEC)
>
>
> -   flags = MFD_CLOEXEC;
> +#if defined(MFD_ALLOW_SEALING)
>
> -   flags |= MFD_ALLOW_SEALING;
> +#endif
>
> -   fd = syscall(__NR_memfd_create, "wayland-cursor", flags);
> if (fd >= 0) {
>
>
> - fd = set_cloexec_or_close(fd);
>
>
> - unlink(tmpname);
>
>
> -   }
>
> - if (ftruncate(fd, size) < 0) {
>
>
> - close(fd);
>
>
> - return -1;
>
>
> - }
>
>
> -
>
> +#if defined(MFD_ALLOW_SEALING)
>
> - if (seal_or_close(fd) != 0)
>
>
> - return -1;
>
>
>
> #endif
>
> - return fd;
>
>
> -   } else if (errno != ENOSYS)
> - return fd;
>
>
>
> +#endif
> +
> +#if defined(FreeBSD)
>
> -   fd = shm_open(SHM_ANON, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600);
> +#else
>
> -   fd = anonymous_shm_open(size);
> +#endif
>
> -
> -   if (ftruncate(fd, size) < 0) {
> - close(fd);
>
>
> - return -1;
>
>
> -   }
> -   return fd;
> }
>
> -/*
>
>
> -   -   Create a new, unique, anonymous file of the given size, and
> -   -   return the file descriptor for it. The file descriptor is set
> -   -   CLOEXEC. The file is immediately suitable for mmap()'ing
> -   -   the given size at offset zero.
> -   -
> -   -   The file should not have a permanent 

Re: [PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-08-16 Thread Jan Engelhardt

On Thursday 2018-08-16 12:41, Emil Velikov wrote:
>On 15 August 2018 at 15:14, Simon Ser  wrote:
>> On Linux, try using memfd_create and file sealing. Fallback to
>> shm_open on old kernels.
>>
>> On FreeBSD, use shm_open with SHM_ANON.
>>
>> Otherwise, use shm_open with a random name, making sure the name
>> isn't already taken.
>>
>Thinking out loud:
>
>I wonder if the next POSIX standard will finally standardise
>random/anonymous shm files. Be that shm_open+SHM_ANON [...]

According to the shm_open.3 from Linux man-pages-4.16 project,
shm_open is already marked standardized:

CONFORMING TO
   POSIX.1-2001, POSIX.1-2008.
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-08-16 Thread Simon Ser
On August 16, 2018 11:57 AM, Jan Engelhardt  wrote:
> On Thursday 2018-08-16 12:41, Emil Velikov wrote:
>
> > On 15 August 2018 at 15:14, Simon Ser cont...@emersion.fr wrote:
> >
> > > On Linux, try using memfd_create and file sealing. Fallback to
> > > shm_open on old kernels.
> > > On FreeBSD, use shm_open with SHM_ANON.
> > > Otherwise, use shm_open with a random name, making sure the name
> > > isn't already taken.
> >
> > Thinking out loud:
> > I wonder if the next POSIX standard will finally standardise
> > random/anonymous shm files. Be that shm_open+SHM_ANON [...]
>
> According to the shm_open.3 from Linux man-pages-4.16 project,
> shm_open is already marked standardized:
>
> CONFORMING TO
> POSIX.1-2001, POSIX.1-2008.

Yes, but this doesn't include SHM_ANON unfortunately. So we still need
to generate a random name and make sure it hasn't been taken already.
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-08-16 Thread Emil Velikov
On 15 August 2018 at 15:14, Simon Ser  wrote:
> On Linux, try using memfd_create and file sealing. Fallback to
> shm_open on old kernels.
>
> On FreeBSD, use shm_open with SHM_ANON.
>
> Otherwise, use shm_open with a random name, making sure the name
> isn't already taken.
>
Thinking out loud:

I wonder if the next POSIX standard will finally standardise
random/anonymous shm files.
Be that shm_open+SHM_ANON (FreeBSD), shm_mk*temp (OpenBSD) or any
other solution.

-Emil
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] cursor: use memfd_create or shm_open for anonymous in-memory files

2018-08-15 Thread Simon Ser
On Linux, try using memfd_create and file sealing. Fallback to
shm_open on old kernels.

On FreeBSD, use shm_open with SHM_ANON.

Otherwise, use shm_open with a random name, making sure the name
isn't already taken.

Signed-off-by: Simon Ser 
---
 Makefile.am   |   2 +-
 configure.ac  |   4 +-
 cursor/os-compatibility.c | 172 ++
 3 files changed, 86 insertions(+), 92 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 697c517..c612672 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -136,7 +136,7 @@ libwayland_cursor_la_SOURCES =  \
cursor/cursor-data.h\
cursor/xcursor.c\
cursor/xcursor.h
-libwayland_cursor_la_LIBADD = libwayland-client.la
+libwayland_cursor_la_LIBADD = libwayland-client.la -lrt
 
 pkgconfig_DATA += cursor/wayland-cursor.pc
 
diff --git a/configure.ac b/configure.ac
index 9419ae3..d59c61d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,8 +62,8 @@ if test "x$GCC" = "xyes"; then
 fi
 AC_SUBST(GCC_CFLAGS)
 
-AC_CHECK_HEADERS([sys/prctl.h])
-AC_CHECK_FUNCS([accept4 mkostemp posix_fallocate prctl])
+AC_CHECK_HEADERS([sys/prctl.h linux/memfd.h])
+AC_CHECK_FUNCS([accept4 prctl])
 
 AC_ARG_ENABLE([libraries],
  [AC_HELP_STRING([--disable-libraries],
diff --git a/cursor/os-compatibility.c b/cursor/os-compatibility.c
index e972d21..96649e3 100644
--- a/cursor/os-compatibility.c
+++ b/cursor/os-compatibility.c
@@ -25,124 +25,118 @@
 
 #define _GNU_SOURCE
 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef HAVE_LINUX_MEMFD_H
+#include 
+#endif
 
 #include "config.h"
 #include "os-compatibility.h"
 
-#ifndef HAVE_MKOSTEMP
+static void
+randname(char *buf) {
+   struct timespec ts;
+   long r;
+   int i;
+
+   clock_gettime(CLOCK_REALTIME, );
+   r = ts.tv_nsec;
+   for (i = 0; i < 6; ++i) {
+   buf[i] = 'A'+(r&15)+(r&16)*2;
+   r >>= 5;
+   }
+}
+
 static int
-set_cloexec_or_close(int fd)
+anonymous_shm_open(off_t size)
 {
-   long flags;
-
-   if (fd == -1)
-   return -1;
+   char name[] = "/wayland-cursor-XX";
+   int fd, retries = 100;
 
-   flags = fcntl(fd, F_GETFD);
-   if (flags == -1)
-   goto err;
+   do {
+   randname(name + strlen(name) - 6);
 
-   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
-   goto err;
+   --retries;
+   fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 
0600);
+   if (fd >= 0) {
+   shm_unlink(name);
+   return fd;
+   }
+   } while (retries > 0 && errno == EEXIST);
 
-   return fd;
-
-err:
-   close(fd);
return -1;
 }
+
+static int
+seal_or_close(int fd) {
+#if defined(F_ADD_SEALS) && defined(F_SEAL_SHRINK)
+   if (fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK) == -1) {
+   close(fd);
+   return -1;
+   }
 #endif
 
+   return 0;
+}
+
 static int
-create_tmpfile_cloexec(char *tmpname)
+create_anonymous_file(off_t size)
 {
-   int fd;
+   int fd, flags;
 
-#ifdef HAVE_MKOSTEMP
-   fd = mkostemp(tmpname, O_CLOEXEC);
-   if (fd >= 0)
-   unlink(tmpname);
-#else
-   fd = mkstemp(tmpname);
+#if defined(__NR_memfd_create) && defined(MFD_CLOEXEC)
+   flags = MFD_CLOEXEC;
+#if defined(MFD_ALLOW_SEALING)
+   flags |= MFD_ALLOW_SEALING;
+#endif
+   fd = syscall(__NR_memfd_create, "wayland-cursor", flags);
if (fd >= 0) {
-   fd = set_cloexec_or_close(fd);
-   unlink(tmpname);
-   }
+   if (ftruncate(fd, size) < 0) {
+   close(fd);
+   return -1;
+   }
+
+#if defined(MFD_ALLOW_SEALING)
+   if (seal_or_close(fd) != 0)
+   return -1;
 #endif
 
+   return fd;
+   } else if (errno != ENOSYS)
+   return fd;
+#endif
+
+#if defined(__FreeBSD__)
+   fd = shm_open(SHM_ANON, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600);
+#else
+   fd = anonymous_shm_open(size);
+#endif
+
+   if (ftruncate(fd, size) < 0) {
+   close(fd);
+   return -1;
+   }
+
return fd;
 }
 
-/*
- * Create a new, unique, anonymous file of the given size, and
- * return the file descriptor for it. The file descriptor is set
- * CLOEXEC. The file is immediately suitable for mmap()'ing
- * the given size at offset zero.
- *
- * The file should not have a permanent backing store like a disk,
- * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
- *
- * The file name is deleted from the file system.
- *
- * The file is suitable for buffer sharing between processes by
- * transmitting the file descriptor over Unix