Linux: Add memfd_create system call wrapper

Message ID 20171103232445.B2FB241C85DF3@oldenburg.str.redhat.com
State New
Headers show
Series
  • Linux: Add memfd_create system call wrapper
Related show

Commit Message

Florian Weimer Nov. 3, 2017, 11:24 p.m.
The system call is somewhat obscure because it is closely related
to file descriptor sealing.  However, it is also the recommended
way to create alias mappings, which is why it has more general use.

No emulation is provided.  Except for the name of the
/proc/self/fd links, it would be possible to implement an
approximation using O_TMPFILE and tmpfs, but this does not appear
to be worth the added complexity.

2017-11-03  Florian Weimer  <fweimer@redhat.com>

	Linux: Add memfd_create system call wrapper
	* sysdeps/unix/sysv/linux/Makefile [misc] (sysdep_headers): Add
	sys/memfd.h.
	(tests): Add tst-memfd_create.
	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
	* sysdeps/unix/sysv/linux/sys/memfd.h: New file.
	* sysdeps/unix/sysv/linux/**.abilist: Update.
	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.
	* support/Makefile (libsupport-routines): Add xreadlink, xstrndup,
	xunlink.
	(tests): Add tst-xreadlink.
	* support/support.h (xstrndup): Declare.
	* support/xunistd.h (xunlink, xreadlink): Declare.
	* support/temp_file.h (support_create_temp_directory): Declare.
	* support/temp_file.c (support_create_temp_directory): New function.
	* support/support_chroot.c (support_chroot_create): Use it.
	* support/xreadlink.c: New file.
	* support/xstrndup.c: Likewise.
	* support/xunlink.c: Likewise.
	* support/tst-xreadlink.c: Likewise.

Comments

Joseph Myers Nov. 3, 2017, 11:48 p.m. | #1
This should have a NEWS entry.  (I have not otherwise reviewed the patch, 
but support the general principle of adding bindings for non-obsolete 
syscalls, including as Linux-specific APIs if we don't think they are 
appropriate for the OS-independent GNU API with a generic ENOSYS version.)
Florian Weimer Nov. 3, 2017, 11:53 p.m. | #2
On 11/04/2017 12:48 AM, Joseph Myers wrote:
> This should have a NEWS entry.  (I have not otherwise reviewed the patch,
> but support the general principle of adding bindings for non-obsolete
> syscalls, including as Linux-specific APIs if we don't think they are
> appropriate for the OS-independent GNU API with a generic ENOSYS version.)

Thanks.  I added this to my local copy:

* glibc now provides the <sys/memfd.h> header file and the memfd_create
   system call.

Florian
Adhemerval Zanella Nov. 8, 2017, 8:24 p.m. | #3
On 03/11/2017 21:24, Florian Weimer wrote:
> The system call is somewhat obscure because it is closely related
> to file descriptor sealing.  However, it is also the recommended
> way to create alias mappings, which is why it has more general use.
> 
> No emulation is provided.  Except for the name of the
> /proc/self/fd links, it would be possible to implement an
> approximation using O_TMPFILE and tmpfs, but this does not appear
> to be worth the added complexity.

I agree an emulation is not worth the trouble.

> 
> 2017-11-03  Florian Weimer  <fweimer@redhat.com>
> 
> 	Linux: Add memfd_create system call wrapper
> 	* sysdeps/unix/sysv/linux/Makefile [misc] (sysdep_headers): Add
> 	sys/memfd.h.
> 	(tests): Add tst-memfd_create.
> 	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
> 	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
> 	* sysdeps/unix/sysv/linux/sys/memfd.h: New file.
> 	* sysdeps/unix/sysv/linux/**.abilist: Update.
> 	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.
> 	* support/Makefile (libsupport-routines): Add xreadlink, xstrndup,
> 	xunlink.
> 	(tests): Add tst-xreadlink.
> 	* support/support.h (xstrndup): Declare.
> 	* support/xunistd.h (xunlink, xreadlink): Declare.
> 	* support/temp_file.h (support_create_temp_directory): Declare.
> 	* support/temp_file.c (support_create_temp_directory): New function.
> 	* support/support_chroot.c (support_chroot_create): Use it.
> 	* support/xreadlink.c: New file.
> 	* support/xstrndup.c: Likewise.
> 	* support/xunlink.c: Likewise.
> 	* support/tst-xreadlink.c: Likewise.
> 

Missing sysdeps/unix/sysv/linux/tst-memfd_create.c entry.


> diff --git a/manual/llio.texi b/manual/llio.texi
> index e72c53c785..5ab68e1511 100644
> --- a/manual/llio.texi
> +++ b/manual/llio.texi
> @@ -1775,6 +1775,40 @@ the given @var{name} previously created by @code{shm_open}.
>  On failure @code{errno} is set.
>  @end deftypefn
>  
> +@deftypefn Function int memfd_create (const char *@var{name}, unsigned int flags)
> +@standards{Linux, sys/memfd.h}
> +
> +The @code{memfd_create} function returns a file descriptor which can be
> +used to create memory mappings using the @code{mmap} function.  It is
> +similar to the @code{shm_open} function in the sense that these mappings
> +are not backed by actual files.  However, the descriptor return by
> +@code{memfd_create} does not correspond to a named object; the
> +@var{name} argument is used for informative purposes only.  The
> +descriptor can be passed between processes (for example, over local
> +domain sockets), and mappings at the same offset refer to the same
> +memory, or the descriptor can be used to create alias mappings within
> +the same process.
> +
> +The descriptor initially refers to a zero-length file.  Before mappings
> +can be created which are backed by memory, the file size needs to be
> +increased with the @code{ftruncate} function.  @xref{File Size}.
> +
> +The @var{flags} argument can be a combination of the following flags:
> +
> +@table @code
> +@item MFD_CLOEXEC
> +The descriptor is created with the @code{O_CLOEXEC} flag.
> +
> +@item MFD_ALLOW_SEALING
> +The descriptor supports the addition of seals using the @code{fcntl}
> +function.
> +@end table
> +
> +The @code{memfd_create} function is specific to Linux.
> +
> +@end deftypefn
> +
> +
>  @node Waiting for I/O
>  @section Waiting for Input or Output
>  @cindex waiting for input or output

Ok.

> diff --git a/support/Makefile b/support/Makefile
> index 027a663000..dafb1737a4 100644
> --- a/support/Makefile
> +++ b/support/Makefile
> @@ -109,19 +109,22 @@ libsupport-routines = \
>    xpthread_once \
>    xpthread_rwlock_init \
>    xpthread_rwlock_rdlock \
> -  xpthread_rwlock_wrlock \
>    xpthread_rwlock_unlock \
> +  xpthread_rwlock_wrlock \
>    xpthread_rwlockattr_init \
>    xpthread_rwlockattr_setkind_np \
>    xpthread_sigmask \
>    xpthread_spin_lock \
>    xpthread_spin_unlock \
> +  xreadlink \
>    xrealloc \
>    xrecvfrom \
>    xsendto \
>    xsetsockopt \
>    xsocket \
>    xstrdup \
> +  xstrndup \
> +  xunlink \
>    xwaitpid \
>    xwrite \
>  
> @@ -138,6 +141,7 @@ tests = \
>    tst-support_capture_subprocess \
>    tst-support_format_dns_packet \
>    tst-support_record_failure \
> +  tst-xreadlink \
>  
>  ifeq ($(run-built-tests),yes)
>  tests-special = \
> diff --git a/support/support.h b/support/support.h
> index 4b5f04c2cc..bbba803ba1 100644
> --- a/support/support.h
> +++ b/support/support.h
> @@ -68,6 +68,7 @@ void *xrealloc (void *p, size_t n);
>  char *xasprintf (const char *format, ...)
>    __attribute__ ((format (printf, 1, 2), malloc));
>  char *xstrdup (const char *);
> +char *xstrndup (const char *, size_t);
>  
>  __END_DECLS
>  

Ok.

> diff --git a/support/support_chroot.c b/support/support_chroot.c
> index f3ef551b05..f6fad18f33 100644
> --- a/support/support_chroot.c
> +++ b/support/support_chroot.c
> @@ -46,10 +46,11 @@ support_chroot_create (struct support_chroot_configuration conf)
>  {
>    struct support_chroot *chroot = xmalloc (sizeof (*chroot));
>  
> -  chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
> -  if (mkdtemp (chroot->path_chroot) == NULL)
> -    FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot);
> -  add_temp_file (chroot->path_chroot);
> +  {
> +    char *template = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
> +    chroot->path_chroot = support_create_temp_directory (template);
> +    free (template);
> +  }
>  
>    /* Create the /etc directory in the chroot environment.  */
>    char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);

Ok.

> diff --git a/support/temp_file.c b/support/temp_file.c
> index fdb2477ab9..cbd54e2e17 100644
> --- a/support/temp_file.c
> +++ b/support/temp_file.c
> @@ -86,6 +86,19 @@ create_temp_file (const char *base, char **filename)
>    return fd;
>  }
>  
> +char *
> +support_create_temp_directory (const char *base)
> +{
> +  char *base_copy = xstrdup (base);
> +  if (mkdtemp (base_copy) == NULL)
> +    {
> +      printf ("error: mkdtemp (\"%s\"): %m", base);
> +      exit (1);
> +    }
> +  add_temp_file (base_copy);
> +  return base_copy;
> +}
> +
>  /* Helper functions called by the test skeleton follow.  */
>  
>  void

Ok.

> diff --git a/support/temp_file.h b/support/temp_file.h
> index 6fed8df1ea..dfefe585de 100644
> --- a/support/temp_file.h
> +++ b/support/temp_file.h
> @@ -32,6 +32,11 @@ void add_temp_file (const char *name);
>     *FILENAME.  */
>  int create_temp_file (const char *base, char **filename);
>  
> +/* Create a temporary directory and schedule it for deletion.  BASE
> +   must end with the six characters "XXXXXX".  Return the name of the
> +   temporary directory.  The caller should free the string.  */
> +char *support_create_temp_directory (const char *base);
> +
>  __END_DECLS
>  
>  #endif /* SUPPORT_TEMP_FILE_H */

Ok.

> diff --git a/support/tst-xreadlink.c b/support/tst-xreadlink.c
> new file mode 100644
> index 0000000000..cb2c12a888
> --- /dev/null
> +++ b/support/tst-xreadlink.c
> @@ -0,0 +1,72 @@
> +/* Test the xreadlink function.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xunistd.h>
> +
> +static int
> +do_test (void)
> +{
> +  char *dir = support_create_temp_directory ("/tmp/tst-xreadlink-XXXXXX");
> +  char *symlink_name = xasprintf ("%s/symlink", dir);
> +  add_temp_file (symlink_name);
> +
> +  /* The limit 10000 is arbitrary and simply there to prevent an
> +     attempt to exhaust all available disk space.  */
> +  for (int size = 1; size < 10000; ++size)
> +    {
> +      char *contents = xmalloc (size + 1);
> +      for (int i = 0; i < size; ++i)
> +        contents[i] = 'a' + (rand () % 26);
> +      contents[size] = '\0';
> +      if (symlink (contents, symlink_name) != 0)
> +        {
> +          if (errno == ENAMETOOLONG)
> +            {
> +              printf ("info: ENAMETOOLONG failure at %d bytes\n", size);
> +              free (contents);
> +              break;
> +            }
> +          FAIL_EXIT1 ("symlink (%d bytes): %m", size);
> +        }
> +
> +      char *readlink_result = xreadlink (symlink_name);
> +      TEST_VERIFY (strcmp (readlink_result, contents) == 0);
> +      free (readlink_result);
> +      xunlink (symlink_name);
> +      free (contents);
> +    }
> +
> +  /* Create an empty file to suppress the temporary file deletion
> +     warning.  */
> +  xclose (xopen (symlink_name, O_WRONLY | O_CREAT, 0));
> +
> +  free (symlink_name);
> +  free (dir);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

I think it is better to split this test and the xreadlink 
addition on another patch.


> diff --git a/support/xreadlink.c b/support/xreadlink.c
> new file mode 100644
> index 0000000000..aec58a2aa6
> --- /dev/null
> +++ b/support/xreadlink.c
> @@ -0,0 +1,44 @@
> +/* Error-checking, allocating wrapper for readlink.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <scratch_buffer.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <xunistd.h>
> +
> +char *
> +xreadlink (const char *path)
> +{
> +  struct scratch_buffer buf;
> +  scratch_buffer_init (&buf);
> +
> +  while (true)
> +    {
> +      ssize_t count = readlink (path, buf.data, buf.length);
> +      if (count < 0)
> +        FAIL_EXIT1 ("readlink (\"%s\"): %m", path);
> +      if (count < buf.length)
> +        {
> +          char *result = xstrndup (buf.data, count);
> +          scratch_buffer_free (&buf);
> +          return result;
> +        }
> +      if (!scratch_buffer_grow (&buf))
> +        FAIL_EXIT1 ("scratch_buffer_grow in xreadlink");
> +    }
> +}

I am not very found this way to handle unknown buffer size 
requirements, but the other possible option I can think of
(lstat plus realloc) is not really different.

Ok.

> diff --git a/support/xstrndup.c b/support/xstrndup.c
> new file mode 100644
> index 0000000000..d59a283d25
> --- /dev/null
> +++ b/support/xstrndup.c
> @@ -0,0 +1,30 @@
> +/* strndup with error checking.
> +   Copyright (C) 2016-2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <support/support.h>
> +
> +#include <string.h>
> +
> +char *
> +xstrndup (const char *s, size_t length)
> +{
> +  char *p = strndup (s, length);
> +  if (p == NULL)
> +    oom_error ("strndup", length);
> +  return p;
> +}

Ok.

> diff --git a/support/xunistd.h b/support/xunistd.h
> index c947bfd8fb..05c2626a7b 100644
> --- a/support/xunistd.h
> +++ b/support/xunistd.h
> @@ -38,6 +38,11 @@ int xopen (const char *path, int flags, mode_t);
>  void xstat (const char *path, struct stat64 *);
>  void xmkdir (const char *path, mode_t);
>  void xchroot (const char *path);
> +void xunlink (const char *path);
> +
> +/* Read the link at PATH.  The caller should free the returned string
> +   with free.  */
> +char *xreadlink (const char *path);
>  
>  /* Close the file descriptor.  Ignore EINTR errors, but terminate the
>     process on other errors.  */

Ok.

> diff --git a/support/xunlink.c b/support/xunlink.c
> new file mode 100644
> index 0000000000..f94ee118cf
> --- /dev/null
> +++ b/support/xunlink.c
> @@ -0,0 +1,27 @@
> +/* Error-checking wrapper for unlink.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +#include <support/xunistd.h>
> +
> +void
> +xunlink (const char *path)
> +{
> +  if (unlink (path) != 0)
> +    FAIL_EXIT1 ("unlink (\"%s\"): %m", path);
> +}

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 0c8a009b5e..3a5515d092 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -39,7 +39,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  sys/klog.h \
>  		  sys/user.h sys/prctl.h \
>  		  sys/kd.h sys/soundcard.h sys/vt.h \
> -		  sys/quota.h sys/fsuid.h \
> +		  sys/quota.h sys/fsuid.h sys/memfd.h \
>  		  scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \
>  		  sys/raw.h sys/personality.h sys/epoll.h \
>  		  bits/a.out.h sys/inotify.h sys/signalfd.h sys/eventfd.h \
> @@ -50,7 +50,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
> -	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max
> +	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max \
> +	 tst-memfd_create
>  
>  # Generate the list of SYS_* macros for the system calls (__NR_*
>  # macros).  The file syscall-names.list contains all possible system

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index 6c9e06f4f9..992c19729f 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -166,6 +166,9 @@ libc {
>    GLIBC_2.15 {
>      process_vm_readv; process_vm_writev;
>    }
> +  GLIBC_2.27 {
> +    memfd_create;
> +  }
>    GLIBC_PRIVATE {
>      # functions used in other libraries
>      __syscall_rt_sigqueueinfo;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index ed598aedac..140ca28abc 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 4e57f36bcf..f698e1b2f4 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
> index 5b70e1bfc9..8a8af3e3e4 100644
> --- a/sysdeps/unix/sysv/linux/arm/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
> @@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.4 GLIBC_2.4 A
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 6a2500a8b3..5b81a6cd7d 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 9ab4e3642a..51ead9e867 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index 81bb623fe8..78b4ee8d40 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 5a33b57390..d9c97779e4 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.4 GLIBC_2.4 A
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 50a86e74fa..4acbf7eeed 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> index 250ef305c3..93f02f08ce 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> @@ -2106,3 +2106,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 87a1dc4ad7..795e85de70 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index f2b35f250e..dc714057b7 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index ade654dbea..ce7bc9b175 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 56032c3f82..3fdd85eace 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index c599dd9212..3e0bcb2a5c 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2147,3 +2147,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 385409aa6e..375c69d9d1 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index e99cb454b5..a88172a906 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> index 173672ab5e..fa026a332c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> @@ -2201,3 +2201,4 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> index 8a654436ab..838f395d78 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 _Exit F
>  GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index dbd411ceb1..41b79c496a 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 5617784ca0..68251a0e69 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
> index 0f840e6e88..bc1aae275e 100644
> --- a/sysdeps/unix/sysv/linux/sh/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
> @@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index bb7e1042c7..93e6d092ac 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 4053b0a51c..b11d6764d4 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/sys/memfd.h b/sysdeps/unix/sysv/linux/sys/memfd.h
> new file mode 100644
> index 0000000000..8255ecd7a4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sys/memfd.h
> @@ -0,0 +1,28 @@
> +/* memfd_create system call and constants.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MEMFD_H
> +#define _SYS_MEMFD_H
> +
> +#include <linux/memfd.h>

How do we handle the case of installed kernels version being lower 
than 3.16 (the one that provides this header)?

> +
> +/* Create a new memory file descriptor.  NAME is a name for debugging.
> +   FLAGS is a combination of the MFD_* constants.  */
> +int memfd_create (const char *__name, unsigned int __flags);
> +
> +#endif /* _SYS_MEMFD_H */
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> index 8bfb080d80..40c4fbb9ea 100644
> --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -109,3 +109,4 @@ setns		EXTRA	setns		i:ii	setns
>  
>  process_vm_readv EXTRA	process_vm_readv i:ipipii process_vm_readv
>  process_vm_writev EXTRA	process_vm_writev i:ipipii process_vm_writev
> +memfd_create    EXTRA	memfd_create	i:si    memfd_create

Ok.

> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> index 38a96d3a02..e9eb4ff7bd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> index 572b917d7d..8f08e909cd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> index 38a96d3a02..e9eb4ff7bd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> new file mode 100644
> index 0000000000..709cf46791
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> @@ -0,0 +1,134 @@
> +/* Test for the memfd_create system call.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/test-driver.h>
> +#include <support/xunistd.h>
> +#include <sys/syscall.h>
> +
> +#ifndef SYS_memfd_create
> +static int
> +do_test (void)
> +{
> +  puts ("warning: kernel headers do not support memfd_create");
> +  return EXIT_UNSUPPORTED;
> +}
> +
> +#else /* SYS_memfd_create */
> +
> +#include <sys/memfd.h>
> +
> +/* Return true if the descriptor has the FD_CLOEXEC flag set.  */
> +static bool
> +is_cloexec (int fd)
> +{
> +  int flags = fcntl (fd, F_GETFD);
> +  TEST_VERIFY (flags >= 0);
> +  return flags & FD_CLOEXEC;
> +}
> +
> +/* Return the seals set on FD.  */
> +static int
> +get_seals (int fd)
> +{
> +  int flags = fcntl (fd, F_GET_SEALS);
> +  TEST_VERIFY (flags >= 0);
> +  return flags;
> +}
> +
> +/* Return true if the F_SEAL_SEAL flag is set on the descriptor.  */
> +static bool
> +is_sealed (int fd)
> +{
> +  return get_seals (fd) & F_SEAL_SEAL;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  /* Initialized by the first call to memfd_create to 0 (memfd_create
> +     unsupported) or 1 (memfd_create is implemented in the kernel).
> +     Subsequent iterations check that the success/failure state is
> +     consistent.  */
> +  int supported = -1;

I am not following why adding this extra logic and the one which
checks SYS_memfd_create.  If __NR_memfd_create is not defined by
kernel headers a stub which returns ENOSYS will be created.  Why
not just bail out with EXIT_UNSUPPORTED if errno is ENOSYS on
first call? Is there any expectation that memfd_create won't
return ENOSYS with different flags?

> +
> +  for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec)
> +    for (int do_sealing = 0; do_sealing < 2; ++do_sealing)
> +      {
> +        int flags = 0;
> +        if (do_cloexec)
> +          flags |= MFD_CLOEXEC;
> +        if (do_sealing)
> +          flags |= MFD_ALLOW_SEALING;
> +        if  (test_verbose > 0)
> +          printf ("info: memfd_create with flags=0x%x\n", flags);
> +        int fd = memfd_create ("tst-memfd_create", flags);
> +        if (fd < 0)
> +          {
> +            if (errno == ENOSYS)
> +              {
> +                if (supported < 0)
> +                  {
> +                    supported = 0;
> +                    continue;
> +                  }
> +                TEST_VERIFY (supported == 0);
> +                continue;
> +              }
> +            else
> +              FAIL_EXIT1 ("memfd_create: %m");
> +          }
> +        if (supported < 0)
> +          supported = 1;
> +        TEST_VERIFY (supported > 0);
> +
> +        char *fd_path = xasprintf ("/proc/self/fd/%d", fd);
> +        char *link = xreadlink (fd_path);
> +        if (test_verbose > 0)
> +          printf ("info: memfd link: %s\n", link);
> +        TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)"));
> +        TEST_VERIFY (is_cloexec (fd) == do_cloexec);
> +        TEST_VERIFY (is_sealed (fd) == !do_sealing);
> +        if (do_sealing)
> +          {
> +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0);
> +            TEST_VERIFY (!is_sealed (fd));
> +            TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE);
> +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0);
> +            TEST_VERIFY (is_sealed (fd));
> +          }
> +        xclose (fd);
> +        free (fd_path);
> +        free (link);
> +      }
> +
> +  if (supported == 0)
> +    return EXIT_UNSUPPORTED;
> +  return 0;
> +}
> +
> +#endif /* SYS_memfd_create */
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index b83d25c2e3..0a4f7797ac 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index cba1d59057..23f6a91429 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2120,3 +2120,4 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>
Florian Weimer Nov. 12, 2017, 9:04 a.m. | #4
* Adhemerval Zanella:

>> 2017-11-03  Florian Weimer  <fweimer@redhat.com>
>> 
>> 	Linux: Add memfd_create system call wrapper
>> 	* sysdeps/unix/sysv/linux/Makefile [misc] (sysdep_headers): Add
>> 	sys/memfd.h.
>> 	(tests): Add tst-memfd_create.
>> 	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
>> 	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
>> 	* sysdeps/unix/sysv/linux/sys/memfd.h: New file.
>> 	* sysdeps/unix/sysv/linux/**.abilist: Update.
>> 	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.
>> 	* support/Makefile (libsupport-routines): Add xreadlink, xstrndup,
>> 	xunlink.
>> 	(tests): Add tst-xreadlink.
>> 	* support/support.h (xstrndup): Declare.
>> 	* support/xunistd.h (xunlink, xreadlink): Declare.
>> 	* support/temp_file.h (support_create_temp_directory): Declare.
>> 	* support/temp_file.c (support_create_temp_directory): New function.
>> 	* support/support_chroot.c (support_chroot_create): Use it.
>> 	* support/xreadlink.c: New file.
>> 	* support/xstrndup.c: Likewise.
>> 	* support/xunlink.c: Likewise.
>> 	* support/tst-xreadlink.c: Likewise.
>> 
>
> Missing sysdeps/unix/sysv/linux/tst-memfd_create.c entry.

Fixed locally.

>> diff --git a/support/tst-xreadlink.c b/support/tst-xreadlink.c
>> new file mode 100644
>> index 0000000000..cb2c12a888
>> --- /dev/null
>> +++ b/support/tst-xreadlink.c

> I think it is better to split this test and the xreadlink 
> addition on another patch.

Okay, I will commit this separately soon.

>> +#ifndef _SYS_MEMFD_H
>> +#define _SYS_MEMFD_H
>> +
>> +#include <linux/memfd.h>
>
> How do we handle the case of installed kernels version being lower 
> than 3.16 (the one that provides this header)?

Then applications will not be able to use this header.

If that's not acceptable, we should probably not add <sys/memfd.h> at
all, but replicate the UAPI constants in <sys/mman.h>.

I see that this also affects the test.  So we probably should go the
<sys/mman.h> route.

>> +static int
>> +do_test (void)
>> +{
>> +  /* Initialized by the first call to memfd_create to 0 (memfd_create
>> +     unsupported) or 1 (memfd_create is implemented in the kernel).
>> +     Subsequent iterations check that the success/failure state is
>> +     consistent.  */
>> +  int supported = -1;
>
> I am not following why adding this extra logic and the one which
> checks SYS_memfd_create.  If __NR_memfd_create is not defined by
> kernel headers a stub which returns ENOSYS will be created.  Why
> not just bail out with EXIT_UNSUPPORTED if errno is ENOSYS on
> first call? Is there any expectation that memfd_create won't
> return ENOSYS with different flags?

I wanted to test that the results are consistent independent of the
flags.  Doesn't this make sense?
Florian Weimer Nov. 12, 2017, 2:51 p.m. | #5
On 11/12/2017 10:04 AM, Florian Weimer wrote:
> If that's not acceptable, we should probably not add <sys/memfd.h> at
> all, but replicate the UAPI constants in <sys/mman.h>.
> 
> I see that this also affects the test.  So we probably should go the
> <sys/mman.h> route.

I had already taken care of that, I forgot.  Anyway, the attached patch 
has the <sys/mman.h> variant of the system call wrapper.

Thanks,
Florian
The system call is somewhat obscure because it is closely related
to file descriptor sealing.  However, it is also the recommended
way to create alias mappings, which is why it has more general use.

No emulation is provided.  Except for the name of the
/proc/self/fd links, it would be possible to implement an
approximation using O_TMPFILE and tmpfs, but this does not appear
to be worth the added complexity.

2017-11-12  Florian Weimer  <fweimer@redhat.com>

	Linux: Add memfd_create system call wrapper
	* sysdeps/unix/sysv/linux/Makefile [misc] (tests): Add
	tst-memfd_create.
	* sysdeps/unix/sysv/linux/bits/mman-linux.h [__USE_GNU]
	(MFD_CLOEXEC, MFD_ALLOW_SEALING): Define.
	[__USE_GNU] (memfd_create): Declare.
	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
	* sysdeps/unix/sysv/linux/tst-memfd_create.c: New file.
	* sysdeps/unix/sysv/linux/**.abilist: Update.
	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.

diff --git a/NEWS b/NEWS
index b7281621f4..eca0c00a9b 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,9 @@ Major new features:
   are the same interfaces added in version 2.26 for some platforms where
   this format is supported but is not the format of long double.
 
+* glibc now provides the <sys/memfd.h> header file and the memfd_create
+  system call.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer
diff --git a/manual/llio.texi b/manual/llio.texi
index 10ad546723..59eb3af711 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -1775,6 +1775,40 @@ the given @var{name} previously created by @code{shm_open}.
 On failure @code{errno} is set.
 @end deftypefn
 
+@deftypefn Function int memfd_create (const char *@var{name}, unsigned int flags)
+@standards{Linux, sys/mman.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+The @code{memfd_create} function returns a file descriptor which can be
+used to create memory mappings using the @code{mmap} function.  It is
+similar to the @code{shm_open} function in the sense that these mappings
+are not backed by actual files.  However, the descriptor return by
+@code{memfd_create} does not correspond to a named object; the
+@var{name} argument is used for informative purposes only.  The
+descriptor can be passed between processes (for example, over local
+domain sockets), and mappings at the same offset refer to the same
+memory, or the descriptor can be used to create alias mappings within
+the same process.
+
+The descriptor initially refers to a zero-length file.  Before mappings
+can be created which are backed by memory, the file size needs to be
+increased with the @code{ftruncate} function.  @xref{File Size}.
+
+The @var{flags} argument can be a combination of the following flags:
+
+@table @code
+@item MFD_CLOEXEC
+The descriptor is created with the @code{O_CLOEXEC} flag.
+
+@item MFD_ALLOW_SEALING
+The descriptor supports the addition of seals using the @code{fcntl}
+function.
+@end table
+
+The @code{memfd_create} function is specific to Linux.
+
+@end deftypefn
+
+
 @node Waiting for I/O
 @section Waiting for Input or Output
 @cindex waiting for input or output
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index bf76b8773d..f974ac446b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -43,7 +43,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
-	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max
+	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max \
+	 tst-memfd_create
 
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index d3dbcde8c9..6f2fe516d7 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -166,6 +166,9 @@ libc {
   GLIBC_2.15 {
     process_vm_readv; process_vm_writev;
   }
+  GLIBC_2.27 {
+    memfd_create;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index ed598aedac..140ca28abc 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 4e57f36bcf..f698e1b2f4 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 5b70e1bfc9..8a8af3e3e4 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h
index b091181960..396829482a 100644
--- a/sysdeps/unix/sysv/linux/bits/mman-linux.h
+++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h
@@ -109,3 +109,18 @@
 # define MCL_ONFAULT	4		/* Lock all pages that are
 					   faulted in.  */
 #endif
+
+#ifdef __USE_GNU
+/* Flags for memfd_create.  */
+# define MFD_CLOEXEC 1U
+# define MFD_ALLOW_SEALING 2U
+
+__BEGIN_DECLS
+
+/* Create a new memory file descriptor.  NAME is a name for debugging.
+   FLAGS is a combination of the MFD_* constants.  */
+int memfd_create (const char *__name, unsigned int __flags) __THROW;
+
+__END_DECLS
+
+#endif /* __USE_GNU */
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 6a2500a8b3..5b81a6cd7d 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 9ab4e3642a..51ead9e867 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 81bb623fe8..78b4ee8d40 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 5a33b57390..d9c97779e4 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 50a86e74fa..4acbf7eeed 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 250ef305c3..93f02f08ce 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2106,3 +2106,4 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 87a1dc4ad7..795e85de70 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index f2b35f250e..dc714057b7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ade654dbea..ce7bc9b175 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 56032c3f82..3fdd85eace 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index c599dd9212..3e0bcb2a5c 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2147,3 +2147,4 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 385409aa6e..375c69d9d1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e99cb454b5..a88172a906 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 173672ab5e..fa026a332c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2201,3 +2201,4 @@ GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 8a654436ab..838f395d78 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index dbd411ceb1..41b79c496a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 5617784ca0..68251a0e69 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 0f840e6e88..bc1aae275e 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index bb7e1042c7..93e6d092ac 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 4053b0a51c..b11d6764d4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 8bfb080d80..40c4fbb9ea 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -109,3 +109,4 @@ setns		EXTRA	setns		i:ii	setns
 
 process_vm_readv EXTRA	process_vm_readv i:ipipii process_vm_readv
 process_vm_writev EXTRA	process_vm_writev i:ipipii process_vm_writev
+memfd_create    EXTRA	memfd_create	i:si    memfd_create
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index 38a96d3a02..e9eb4ff7bd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 572b917d7d..8f08e909cd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index 38a96d3a02..e9eb4ff7bd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c
new file mode 100644
index 0000000000..fd173ff71d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c
@@ -0,0 +1,121 @@
+/* Test for the memfd_create system call.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+
+/* Return true if the descriptor has the FD_CLOEXEC flag set.  */
+static bool
+is_cloexec (int fd)
+{
+  int flags = fcntl (fd, F_GETFD);
+  TEST_VERIFY (flags >= 0);
+  return flags & FD_CLOEXEC;
+}
+
+/* Return the seals set on FD.  */
+static int
+get_seals (int fd)
+{
+  int flags = fcntl (fd, F_GET_SEALS);
+  TEST_VERIFY (flags >= 0);
+  return flags;
+}
+
+/* Return true if the F_SEAL_SEAL flag is set on the descriptor.  */
+static bool
+is_sealed (int fd)
+{
+  return get_seals (fd) & F_SEAL_SEAL;
+}
+
+static int
+do_test (void)
+{
+  /* Initialized by the first call to memfd_create to 0 (memfd_create
+     unsupported) or 1 (memfd_create is implemented in the kernel).
+     Subsequent iterations check that the success/failure state is
+     consistent.  */
+  int supported = -1;
+
+  for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec)
+    for (int do_sealing = 0; do_sealing < 2; ++do_sealing)
+      {
+        int flags = 0;
+        if (do_cloexec)
+          flags |= MFD_CLOEXEC;
+        if (do_sealing)
+          flags |= MFD_ALLOW_SEALING;
+        if  (test_verbose > 0)
+          printf ("info: memfd_create with flags=0x%x\n", flags);
+        int fd = memfd_create ("tst-memfd_create", flags);
+        if (fd < 0)
+          {
+            if (errno == ENOSYS)
+              {
+                if (supported < 0)
+                  {
+                    printf ("warning: memfd_create is unsupported\n");
+                    supported = 0;
+                    continue;
+                  }
+                TEST_VERIFY (supported == 0);
+                continue;
+              }
+            else
+              FAIL_EXIT1 ("memfd_create: %m");
+          }
+        if (supported < 0)
+          supported = 1;
+        TEST_VERIFY (supported > 0);
+
+        char *fd_path = xasprintf ("/proc/self/fd/%d", fd);
+        char *link = xreadlink (fd_path);
+        if (test_verbose > 0)
+          printf ("info: memfd link: %s\n", link);
+        TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)"));
+        TEST_VERIFY (is_cloexec (fd) == do_cloexec);
+        TEST_VERIFY (is_sealed (fd) == !do_sealing);
+        if (do_sealing)
+          {
+            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0);
+            TEST_VERIFY (!is_sealed (fd));
+            TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE);
+            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0);
+            TEST_VERIFY (is_sealed (fd));
+          }
+        xclose (fd);
+        free (fd_path);
+        free (link);
+      }
+
+  if (supported == 0)
+    return EXIT_UNSUPPORTED;
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index b83d25c2e3..0a4f7797ac 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index cba1d59057..23f6a91429 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2120,3 +2120,4 @@ GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
Adhemerval Zanella Nov. 16, 2017, 10:34 a.m. | #6
On 12/11/2017 12:51, Florian Weimer wrote:
> On 11/12/2017 10:04 AM, Florian Weimer wrote:
>> If that's not acceptable, we should probably not add <sys/memfd.h> at
>> all, but replicate the UAPI constants in <sys/mman.h>.
>>
>> I see that this also affects the test.  So we probably should go the
>> <sys/mman.h> route.
> 
> I had already taken care of that, I forgot.  Anyway, the attached patch has the <sys/mman.h> variant of the system call wrapper.
> 
> Thanks,
> Florian
> 
> memfd.patch
> 
> 
> The system call is somewhat obscure because it is closely related
> to file descriptor sealing.  However, it is also the recommended
> way to create alias mappings, which is why it has more general use.
> 
> No emulation is provided.  Except for the name of the
> /proc/self/fd links, it would be possible to implement an
> approximation using O_TMPFILE and tmpfs, but this does not appear
> to be worth the added complexity.
> 
> 2017-11-12  Florian Weimer  <fweimer@redhat.com>
> 
> 	Linux: Add memfd_create system call wrapper
> 	* sysdeps/unix/sysv/linux/Makefile [misc] (tests): Add
> 	tst-memfd_create.
> 	* sysdeps/unix/sysv/linux/bits/mman-linux.h [__USE_GNU]
> 	(MFD_CLOEXEC, MFD_ALLOW_SEALING): Define.
> 	[__USE_GNU] (memfd_create): Declare.
> 	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
> 	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
> 	* sysdeps/unix/sysv/linux/tst-memfd_create.c: New file.
> 	* sysdeps/unix/sysv/linux/**.abilist: Update.
> 	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.

LGTM with just an update below.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

> 
> diff --git a/NEWS b/NEWS
> index b7281621f4..eca0c00a9b 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -35,6 +35,9 @@ Major new features:
>    are the same interfaces added in version 2.26 for some platforms where
>    this format is supported but is not the format of long double.
>  
> +* glibc now provides the <sys/memfd.h> header file and the memfd_create
> +  system call.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>  * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer

Ok.

> diff --git a/manual/llio.texi b/manual/llio.texi
> index 10ad546723..59eb3af711 100644
> --- a/manual/llio.texi
> +++ b/manual/llio.texi
> @@ -1775,6 +1775,40 @@ the given @var{name} previously created by @code{shm_open}.
>  On failure @code{errno} is set.
>  @end deftypefn
>  
> +@deftypefn Function int memfd_create (const char *@var{name}, unsigned int flags)
> +@standards{Linux, sys/mman.h}
> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
> +The @code{memfd_create} function returns a file descriptor which can be
> +used to create memory mappings using the @code{mmap} function.  It is
> +similar to the @code{shm_open} function in the sense that these mappings
> +are not backed by actual files.  However, the descriptor return by
> +@code{memfd_create} does not correspond to a named object; the
> +@var{name} argument is used for informative purposes only.  The
> +descriptor can be passed between processes (for example, over local
> +domain sockets), and mappings at the same offset refer to the same
> +memory, or the descriptor can be used to create alias mappings within
> +the same process.
> +
> +The descriptor initially refers to a zero-length file.  Before mappings
> +can be created which are backed by memory, the file size needs to be
> +increased with the @code{ftruncate} function.  @xref{File Size}.
> +
> +The @var{flags} argument can be a combination of the following flags:
> +
> +@table @code
> +@item MFD_CLOEXEC
> +The descriptor is created with the @code{O_CLOEXEC} flag.
> +
> +@item MFD_ALLOW_SEALING
> +The descriptor supports the addition of seals using the @code{fcntl}
> +function.
> +@end table
> +
> +The @code{memfd_create} function is specific to Linux.
> +
> +@end deftypefn
> +
> +
>  @node Waiting for I/O
>  @section Waiting for Input or Output
>  @cindex waiting for input or output

Linux 4.14 (749df87bd7be) added a new flag MFD_HUGETLB. I think ww should add
and document it.

> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index bf76b8773d..f974ac446b 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -43,7 +43,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
> -	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max
> +	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max \
> +	 tst-memfd_create
>  
>  # Generate the list of SYS_* macros for the system calls (__NR_*
>  # macros).  The file syscall-names.list contains all possible system

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index d3dbcde8c9..6f2fe516d7 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -166,6 +166,9 @@ libc {
>    GLIBC_2.15 {
>      process_vm_readv; process_vm_writev;
>    }
> +  GLIBC_2.27 {
> +    memfd_create;
> +  }
>    GLIBC_PRIVATE {
>      # functions used in other libraries
>      __syscall_rt_sigqueueinfo;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index ed598aedac..140ca28abc 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 4e57f36bcf..f698e1b2f4 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
> index 5b70e1bfc9..8a8af3e3e4 100644
> --- a/sysdeps/unix/sysv/linux/arm/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
> @@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.4 GLIBC_2.4 A
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h
> index b091181960..396829482a 100644
> --- a/sysdeps/unix/sysv/linux/bits/mman-linux.h
> +++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h
> @@ -109,3 +109,18 @@
>  # define MCL_ONFAULT	4		/* Lock all pages that are
>  					   faulted in.  */
>  #endif
> +
> +#ifdef __USE_GNU
> +/* Flags for memfd_create.  */
> +# define MFD_CLOEXEC 1U
> +# define MFD_ALLOW_SEALING 2U
> +
> +__BEGIN_DECLS
> +
> +/* Create a new memory file descriptor.  NAME is a name for debugging.
> +   FLAGS is a combination of the MFD_* constants.  */
> +int memfd_create (const char *__name, unsigned int __flags) __THROW;
> +
> +__END_DECLS
> +
> +#endif /* __USE_GNU */

As before I think we should include MFD_HUGETLB.

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 6a2500a8b3..5b81a6cd7d 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 9ab4e3642a..51ead9e867 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index 81bb623fe8..78b4ee8d40 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 5a33b57390..d9c97779e4 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.4 GLIBC_2.4 A
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 50a86e74fa..4acbf7eeed 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> index 250ef305c3..93f02f08ce 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> @@ -2106,3 +2106,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 87a1dc4ad7..795e85de70 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index f2b35f250e..dc714057b7 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index ade654dbea..ce7bc9b175 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 56032c3f82..3fdd85eace 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index c599dd9212..3e0bcb2a5c 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2147,3 +2147,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 385409aa6e..375c69d9d1 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index e99cb454b5..a88172a906 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> index 173672ab5e..fa026a332c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> @@ -2201,3 +2201,4 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> index 8a654436ab..838f395d78 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 _Exit F
>  GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index dbd411ceb1..41b79c496a 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 5617784ca0..68251a0e69 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
> index 0f840e6e88..bc1aae275e 100644
> --- a/sysdeps/unix/sysv/linux/sh/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
> @@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index bb7e1042c7..93e6d092ac 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 4053b0a51c..b11d6764d4 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.27 strfromf128 F
>  GLIBC_2.27 strtof128 F
>  GLIBC_2.27 strtof128_l F
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> index 8bfb080d80..40c4fbb9ea 100644
> --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -109,3 +109,4 @@ setns		EXTRA	setns		i:ii	setns
>  
>  process_vm_readv EXTRA	process_vm_readv i:ipipii process_vm_readv
>  process_vm_writev EXTRA	process_vm_writev i:ipipii process_vm_writev
> +memfd_create    EXTRA	memfd_create	i:si    memfd_create
> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> index 38a96d3a02..e9eb4ff7bd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> index 572b917d7d..8f08e909cd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> index 38a96d3a02..e9eb4ff7bd 100644
> --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
> diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> new file mode 100644
> index 0000000000..fd173ff71d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> @@ -0,0 +1,121 @@
> +/* Test for the memfd_create system call.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/test-driver.h>
> +#include <support/xunistd.h>
> +#include <sys/mman.h>
> +
> +/* Return true if the descriptor has the FD_CLOEXEC flag set.  */
> +static bool
> +is_cloexec (int fd)
> +{
> +  int flags = fcntl (fd, F_GETFD);
> +  TEST_VERIFY (flags >= 0);
> +  return flags & FD_CLOEXEC;
> +}
> +
> +/* Return the seals set on FD.  */
> +static int
> +get_seals (int fd)
> +{
> +  int flags = fcntl (fd, F_GET_SEALS);
> +  TEST_VERIFY (flags >= 0);
> +  return flags;
> +}
> +
> +/* Return true if the F_SEAL_SEAL flag is set on the descriptor.  */
> +static bool
> +is_sealed (int fd)
> +{
> +  return get_seals (fd) & F_SEAL_SEAL;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  /* Initialized by the first call to memfd_create to 0 (memfd_create
> +     unsupported) or 1 (memfd_create is implemented in the kernel).
> +     Subsequent iterations check that the success/failure state is
> +     consistent.  */
> +  int supported = -1;
> +
> +  for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec)
> +    for (int do_sealing = 0; do_sealing < 2; ++do_sealing)
> +      {
> +        int flags = 0;
> +        if (do_cloexec)
> +          flags |= MFD_CLOEXEC;
> +        if (do_sealing)
> +          flags |= MFD_ALLOW_SEALING;
> +        if  (test_verbose > 0)
> +          printf ("info: memfd_create with flags=0x%x\n", flags);
> +        int fd = memfd_create ("tst-memfd_create", flags);
> +        if (fd < 0)
> +          {
> +            if (errno == ENOSYS)
> +              {
> +                if (supported < 0)
> +                  {
> +                    printf ("warning: memfd_create is unsupported\n");
> +                    supported = 0;
> +                    continue;
> +                  }
> +                TEST_VERIFY (supported == 0);
> +                continue;
> +              }
> +            else
> +              FAIL_EXIT1 ("memfd_create: %m");
> +          }
> +        if (supported < 0)
> +          supported = 1;
> +        TEST_VERIFY (supported > 0);
> +
> +        char *fd_path = xasprintf ("/proc/self/fd/%d", fd);
> +        char *link = xreadlink (fd_path);
> +        if (test_verbose > 0)
> +          printf ("info: memfd link: %s\n", link);
> +        TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)"));
> +        TEST_VERIFY (is_cloexec (fd) == do_cloexec);
> +        TEST_VERIFY (is_sealed (fd) == !do_sealing);
> +        if (do_sealing)
> +          {
> +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0);
> +            TEST_VERIFY (!is_sealed (fd));
> +            TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE);
> +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0);
> +            TEST_VERIFY (is_sealed (fd));
> +          }
> +        xclose (fd);
> +        free (fd_path);
> +        free (link);
> +      }
> +
> +  if (supported == 0)
> +    return EXIT_UNSUPPORTED;
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index b83d25c2e3..0a4f7797ac 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>  GLIBC_2.3 GLIBC_2.3 A
>  GLIBC_2.3 __ctype_b_loc F
>  GLIBC_2.3 __ctype_tolower_loc F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index cba1d59057..23f6a91429 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2120,3 +2120,4 @@ GLIBC_2.26 wcstof128_l F
>  GLIBC_2.27 GLIBC_2.27 A
>  GLIBC_2.27 glob F
>  GLIBC_2.27 glob64 F
> +GLIBC_2.27 memfd_create F
>
Christian Brauner Nov. 16, 2017, 1:30 p.m. | #7
On Thu, Nov 16, 2017 at 08:34:26AM -0200, Adhemerval Zanella wrote:
> 
> 
> On 12/11/2017 12:51, Florian Weimer wrote:
> > On 11/12/2017 10:04 AM, Florian Weimer wrote:
> >> If that's not acceptable, we should probably not add <sys/memfd.h> at
> >> all, but replicate the UAPI constants in <sys/mman.h>.

+1 that sounds like a good idea.

> >>
> >> I see that this also affects the test.  So we probably should go the
> >> <sys/mman.h> route.
> > 
> > I had already taken care of that, I forgot.  Anyway, the attached patch has the <sys/mman.h> variant of the system call wrapper.
> > 
> > Thanks,
> > Florian
> > 
> > memfd.patch
> > 
> > 
> > The system call is somewhat obscure because it is closely related
> > to file descriptor sealing.  However, it is also the recommended

Sure and the api is somewhat bogus given this nonesensical "name" argument in
there but it actually has a lot more use-cases for userspace.

> > way to create alias mappings, which is why it has more general use.

For example, systemd and lxc both carry their own memfd_create() definitions
including the appropriate syscall number and option numbers. A concrete use-case
is e.g. using mmap() + memfd_create() to create an efficient (Linux specific)
in-memory ringbuffer ( https://github.com/lxc/lxc/blob/master/src/lxc/ringbuf.c
). In general, both have valid use cases to only have an in-memory file that
can't be covered by mmap() alone. So this is really good to finally have!

> > 
> > No emulation is provided.  Except for the name of the
> > /proc/self/fd links, it would be possible to implement an
> > approximation using O_TMPFILE and tmpfs, but this does not appear
> > to be worth the added complexity.
> > 
> > 2017-11-12  Florian Weimer  <fweimer@redhat.com>
> > 
> > 	Linux: Add memfd_create system call wrapper
> > 	* sysdeps/unix/sysv/linux/Makefile [misc] (tests): Add
> > 	tst-memfd_create.
> > 	* sysdeps/unix/sysv/linux/bits/mman-linux.h [__USE_GNU]
> > 	(MFD_CLOEXEC, MFD_ALLOW_SEALING): Define.
> > 	[__USE_GNU] (memfd_create): Declare.
> > 	* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add memfd_create.
> > 	* sysdeps/unix/sysv/linux/syscalls.list (memfd_create): Add.
> > 	* sysdeps/unix/sysv/linux/tst-memfd_create.c: New file.
> > 	* sysdeps/unix/sysv/linux/**.abilist: Update.
> > 	* manual/llio.texi (Memory-mapped I/O): Document memfd_create.
> 
> LGTM with just an update below.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>

> 
> > 
> > diff --git a/NEWS b/NEWS
> > index b7281621f4..eca0c00a9b 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -35,6 +35,9 @@ Major new features:
> >    are the same interfaces added in version 2.26 for some platforms where
> >    this format is supported but is not the format of long double.
> >  
> > +* glibc now provides the <sys/memfd.h> header file and the memfd_create
> > +  system call.
> > +
> >  Deprecated and removed features, and other changes affecting compatibility:
> >  
> >  * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer
> 
> Ok.
> 
> > diff --git a/manual/llio.texi b/manual/llio.texi
> > index 10ad546723..59eb3af711 100644
> > --- a/manual/llio.texi
> > +++ b/manual/llio.texi
> > @@ -1775,6 +1775,40 @@ the given @var{name} previously created by @code{shm_open}.
> >  On failure @code{errno} is set.
> >  @end deftypefn
> >  
> > +@deftypefn Function int memfd_create (const char *@var{name}, unsigned int flags)
> > +@standards{Linux, sys/mman.h}
> > +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
> > +The @code{memfd_create} function returns a file descriptor which can be
> > +used to create memory mappings using the @code{mmap} function.  It is
> > +similar to the @code{shm_open} function in the sense that these mappings
> > +are not backed by actual files.  However, the descriptor return by
> > +@code{memfd_create} does not correspond to a named object; the
> > +@var{name} argument is used for informative purposes only.  The
> > +descriptor can be passed between processes (for example, over local
> > +domain sockets), and mappings at the same offset refer to the same
> > +memory, or the descriptor can be used to create alias mappings within
> > +the same process.
> > +
> > +The descriptor initially refers to a zero-length file.  Before mappings
> > +can be created which are backed by memory, the file size needs to be
> > +increased with the @code{ftruncate} function.  @xref{File Size}.
> > +
> > +The @var{flags} argument can be a combination of the following flags:
> > +
> > +@table @code
> > +@item MFD_CLOEXEC
> > +The descriptor is created with the @code{O_CLOEXEC} flag.
> > +
> > +@item MFD_ALLOW_SEALING
> > +The descriptor supports the addition of seals using the @code{fcntl}
> > +function.
> > +@end table
> > +
> > +The @code{memfd_create} function is specific to Linux.
> > +
> > +@end deftypefn
> > +
> > +
> >  @node Waiting for I/O
> >  @section Waiting for Input or Output
> >  @cindex waiting for input or output
> 
> Linux 4.14 (749df87bd7be) added a new flag MFD_HUGETLB. I think ww should add
> and document it.
> 
> > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> > index bf76b8773d..f974ac446b 100644
> > --- a/sysdeps/unix/sysv/linux/Makefile
> > +++ b/sysdeps/unix/sysv/linux/Makefile
> > @@ -43,7 +43,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
> >  		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
> >  
> >  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
> > -	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max
> > +	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max \
> > +	 tst-memfd_create
> >  
> >  # Generate the list of SYS_* macros for the system calls (__NR_*
> >  # macros).  The file syscall-names.list contains all possible system
> 
> Ok.
> 
> > diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> > index d3dbcde8c9..6f2fe516d7 100644
> > --- a/sysdeps/unix/sysv/linux/Versions
> > +++ b/sysdeps/unix/sysv/linux/Versions
> > @@ -166,6 +166,9 @@ libc {
> >    GLIBC_2.15 {
> >      process_vm_readv; process_vm_writev;
> >    }
> > +  GLIBC_2.27 {
> > +    memfd_create;
> > +  }
> >    GLIBC_PRIVATE {
> >      # functions used in other libraries
> >      __syscall_rt_sigqueueinfo;
> 
> Ok.
> 
> > diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> > index ed598aedac..140ca28abc 100644
> > --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> > @@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> > index 4e57f36bcf..f698e1b2f4 100644
> > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> > @@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
> > index 5b70e1bfc9..8a8af3e3e4 100644
> > --- a/sysdeps/unix/sysv/linux/arm/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
> > @@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.4 GLIBC_2.4 A
> >  GLIBC_2.4 _Exit F
> >  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> > diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h
> > index b091181960..396829482a 100644
> > --- a/sysdeps/unix/sysv/linux/bits/mman-linux.h
> > +++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h
> > @@ -109,3 +109,18 @@
> >  # define MCL_ONFAULT	4		/* Lock all pages that are
> >  					   faulted in.  */
> >  #endif
> > +
> > +#ifdef __USE_GNU
> > +/* Flags for memfd_create.  */
> > +# define MFD_CLOEXEC 1U
> > +# define MFD_ALLOW_SEALING 2U
> > +
> > +__BEGIN_DECLS
> > +
> > +/* Create a new memory file descriptor.  NAME is a name for debugging.
> > +   FLAGS is a combination of the MFD_* constants.  */
> > +int memfd_create (const char *__name, unsigned int __flags) __THROW;
> > +
> > +__END_DECLS
> > +
> > +#endif /* __USE_GNU */
> 
> As before I think we should include MFD_HUGETLB.
> 
> > diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> > index 6a2500a8b3..5b81a6cd7d 100644
> > --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> > @@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> > index 9ab4e3642a..51ead9e867 100644
> > --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> > @@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> > index 81bb623fe8..78b4ee8d40 100644
> > --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> > @@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> > index 5a33b57390..d9c97779e4 100644
> > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> > @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.4 GLIBC_2.4 A
> >  GLIBC_2.4 _Exit F
> >  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
> > diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> > index 50a86e74fa..4acbf7eeed 100644
> > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> > @@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> > index 250ef305c3..93f02f08ce 100644
> > --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
> > @@ -2106,3 +2106,4 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> > index 87a1dc4ad7..795e85de70 100644
> > --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> > @@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> > index f2b35f250e..dc714057b7 100644
> > --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> > @@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> > index ade654dbea..ce7bc9b175 100644
> > --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> > @@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> > index 56032c3f82..3fdd85eace 100644
> > --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> > @@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> > index c599dd9212..3e0bcb2a5c 100644
> > --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> > @@ -2147,3 +2147,4 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> > index 385409aa6e..375c69d9d1 100644
> > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> > @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> > index e99cb454b5..a88172a906 100644
> > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> > @@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> > index 173672ab5e..fa026a332c 100644
> > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
> > @@ -2201,3 +2201,4 @@ GLIBC_2.26 wcstof128_l F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> > index 8a654436ab..838f395d78 100644
> > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
> > @@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 _Exit F
> >  GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
> > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> > index dbd411ceb1..41b79c496a 100644
> > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> > @@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> > index 5617784ca0..68251a0e69 100644
> > --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> > @@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
> > index 0f840e6e88..bc1aae275e 100644
> > --- a/sysdeps/unix/sysv/linux/sh/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
> > @@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> > index bb7e1042c7..93e6d092ac 100644
> > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> > @@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> > index 4053b0a51c..b11d6764d4 100644
> > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> > @@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.27 strfromf128 F
> >  GLIBC_2.27 strtof128 F
> >  GLIBC_2.27 strtof128_l F
> > diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> > index 8bfb080d80..40c4fbb9ea 100644
> > --- a/sysdeps/unix/sysv/linux/syscalls.list
> > +++ b/sysdeps/unix/sysv/linux/syscalls.list
> > @@ -109,3 +109,4 @@ setns		EXTRA	setns		i:ii	setns
> >  
> >  process_vm_readv EXTRA	process_vm_readv i:ipipii process_vm_readv
> >  process_vm_writev EXTRA	process_vm_writev i:ipipii process_vm_writev
> > +memfd_create    EXTRA	memfd_create	i:si    memfd_create
> > diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> > index 38a96d3a02..e9eb4ff7bd 100644
> > --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
> > @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> > index 572b917d7d..8f08e909cd 100644
> > --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
> > @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> > index 38a96d3a02..e9eb4ff7bd 100644
> > --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
> > @@ -2113,3 +2113,4 @@ GLIBC_2.26 reallocarray F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> > diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> > new file mode 100644
> > index 0000000000..fd173ff71d
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c
> > @@ -0,0 +1,121 @@
> > +/* Test for the memfd_create system call.
> > +   Copyright (C) 2017 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#include <errno.h>
> > +#include <fcntl.h>
> > +#include <stdbool.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <support/check.h>
> > +#include <support/support.h>
> > +#include <support/test-driver.h>
> > +#include <support/xunistd.h>
> > +#include <sys/mman.h>
> > +
> > +/* Return true if the descriptor has the FD_CLOEXEC flag set.  */
> > +static bool
> > +is_cloexec (int fd)
> > +{
> > +  int flags = fcntl (fd, F_GETFD);
> > +  TEST_VERIFY (flags >= 0);
> > +  return flags & FD_CLOEXEC;
> > +}
> > +
> > +/* Return the seals set on FD.  */
> > +static int
> > +get_seals (int fd)
> > +{
> > +  int flags = fcntl (fd, F_GET_SEALS);
> > +  TEST_VERIFY (flags >= 0);
> > +  return flags;
> > +}
> > +
> > +/* Return true if the F_SEAL_SEAL flag is set on the descriptor.  */
> > +static bool
> > +is_sealed (int fd)
> > +{
> > +  return get_seals (fd) & F_SEAL_SEAL;
> > +}
> > +
> > +static int
> > +do_test (void)
> > +{
> > +  /* Initialized by the first call to memfd_create to 0 (memfd_create
> > +     unsupported) or 1 (memfd_create is implemented in the kernel).
> > +     Subsequent iterations check that the success/failure state is
> > +     consistent.  */
> > +  int supported = -1;
> > +
> > +  for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec)
> > +    for (int do_sealing = 0; do_sealing < 2; ++do_sealing)
> > +      {
> > +        int flags = 0;
> > +        if (do_cloexec)
> > +          flags |= MFD_CLOEXEC;
> > +        if (do_sealing)
> > +          flags |= MFD_ALLOW_SEALING;
> > +        if  (test_verbose > 0)
> > +          printf ("info: memfd_create with flags=0x%x\n", flags);
> > +        int fd = memfd_create ("tst-memfd_create", flags);
> > +        if (fd < 0)
> > +          {
> > +            if (errno == ENOSYS)
> > +              {
> > +                if (supported < 0)
> > +                  {
> > +                    printf ("warning: memfd_create is unsupported\n");
> > +                    supported = 0;
> > +                    continue;
> > +                  }
> > +                TEST_VERIFY (supported == 0);
> > +                continue;
> > +              }
> > +            else
> > +              FAIL_EXIT1 ("memfd_create: %m");
> > +          }
> > +        if (supported < 0)
> > +          supported = 1;
> > +        TEST_VERIFY (supported > 0);
> > +
> > +        char *fd_path = xasprintf ("/proc/self/fd/%d", fd);
> > +        char *link = xreadlink (fd_path);
> > +        if (test_verbose > 0)
> > +          printf ("info: memfd link: %s\n", link);
> > +        TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)"));
> > +        TEST_VERIFY (is_cloexec (fd) == do_cloexec);
> > +        TEST_VERIFY (is_sealed (fd) == !do_sealing);
> > +        if (do_sealing)
> > +          {
> > +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0);
> > +            TEST_VERIFY (!is_sealed (fd));
> > +            TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE);
> > +            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0);
> > +            TEST_VERIFY (is_sealed (fd));
> > +          }
> > +        xclose (fd);
> > +        free (fd_path);
> > +        free (link);
> > +      }
> > +
> > +  if (supported == 0)
> > +    return EXIT_UNSUPPORTED;
> > +  return 0;
> > +}
> > +
> > +#include <support/test-driver.c>
> 
> Ok.
> 
> > diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> > index b83d25c2e3..0a4f7797ac 100644
> > --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> > @@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >  GLIBC_2.3 GLIBC_2.3 A
> >  GLIBC_2.3 __ctype_b_loc F
> >  GLIBC_2.3 __ctype_tolower_loc F
> > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> > index cba1d59057..23f6a91429 100644
> > --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> > @@ -2120,3 +2120,4 @@ GLIBC_2.26 wcstof128_l F
> >  GLIBC_2.27 GLIBC_2.27 A
> >  GLIBC_2.27 glob F
> >  GLIBC_2.27 glob64 F
> > +GLIBC_2.27 memfd_create F
> >
Florian Weimer Nov. 17, 2017, 10:20 p.m. | #8
On 11/16/2017 11:34 AM, Adhemerval Zanella wrote:
> Linux 4.14 (749df87bd7be) added a new flag MFD_HUGETLB. I think ww should add
> and document it.

We currently do not document MAP_HUGETLB, which is closely related and 
not really simple to describe.  The manual page and kernel documentation 
do not cover it in detail, either.  The page size selection in 
particular is missing, and I would have to research how an application 
can discover supported hugepage sizes.

In short, this is not exactly a trivial request, and I would kindly ask 
you to reconsider.

Thanks,
Florian
Joseph Myers Nov. 17, 2017, 10:41 p.m. | #9
On Fri, 17 Nov 2017, Florian Weimer wrote:

> On 11/16/2017 11:34 AM, Adhemerval Zanella wrote:
> > Linux 4.14 (749df87bd7be) added a new flag MFD_HUGETLB. I think ww should
> > add
> > and document it.
> 
> We currently do not document MAP_HUGETLB, which is closely related and not
> really simple to describe.  The manual page and kernel documentation do not
> cover it in detail, either.  The page size selection in particular is missing,
> and I would have to research how an application can discover supported
> hugepage sizes.
> 
> In short, this is not exactly a trivial request, and I would kindly ask you to
> reconsider.

Maybe say the new flag should at least be added to the header (unless 
automatically visible via an include of a <linux/*.h> UAPI header), absent 
a reason not to do so, but given the difficulties of doing so we might for 
now not document it (generically, for new constants from new Linux kernel 
releases, as opposed to new functions, that's been the practice for a long 
time).
Florian Weimer Nov. 17, 2017, 10:53 p.m. | #10
On 11/17/2017 11:41 PM, Joseph Myers wrote:
> On Fri, 17 Nov 2017, Florian Weimer wrote:
> 
>> On 11/16/2017 11:34 AM, Adhemerval Zanella wrote:
>>> Linux 4.14 (749df87bd7be) added a new flag MFD_HUGETLB. I think ww should
>>> add
>>> and document it.
>>
>> We currently do not document MAP_HUGETLB, which is closely related and not
>> really simple to describe.  The manual page and kernel documentation do not
>> cover it in detail, either.  The page size selection in particular is missing,
>> and I would have to research how an application can discover supported
>> hugepage sizes.
>>
>> In short, this is not exactly a trivial request, and I would kindly ask you to
>> reconsider.
> 
> Maybe say the new flag should at least be added to the header (unless
> automatically visible via an include of a <linux/*.h> UAPI header), absent
> a reason not to do so, but given the difficulties of doing so we might for
> now not document it (generically, for new constants from new Linux kernel
> releases, as opposed to new functions, that's been the practice for a long
> time).

Would it be okay to pretend that the hugepage size selection mechanism 
doesn't exist?

We haven't added that yet for SHM_HUGETLB, either.

Thanks,
Florian
Joseph Myers Nov. 17, 2017, 11:08 p.m. | #11
On Fri, 17 Nov 2017, Florian Weimer wrote:

> Would it be okay to pretend that the hugepage size selection mechanism doesn't
> exist?

Sure.
Adhemerval Zanella Nov. 18, 2017, 12:16 a.m. | #12
> Il giorno 17 nov 2017, alle ore 21:08, Joseph Myers <joseph@codesourcery.com> ha scritto:
> 
>> On Fri, 17 Nov 2017, Florian Weimer wrote:
>> 
>> Would it be okay to pretend that the hugepage size selection mechanism doesn't
>> exist?
> 
> Sure.

Sounds reasonable to me as well.

Patch

diff --git a/manual/llio.texi b/manual/llio.texi
index e72c53c785..5ab68e1511 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -1775,6 +1775,40 @@  the given @var{name} previously created by @code{shm_open}.
 On failure @code{errno} is set.
 @end deftypefn
 
+@deftypefn Function int memfd_create (const char *@var{name}, unsigned int flags)
+@standards{Linux, sys/memfd.h}
+
+The @code{memfd_create} function returns a file descriptor which can be
+used to create memory mappings using the @code{mmap} function.  It is
+similar to the @code{shm_open} function in the sense that these mappings
+are not backed by actual files.  However, the descriptor return by
+@code{memfd_create} does not correspond to a named object; the
+@var{name} argument is used for informative purposes only.  The
+descriptor can be passed between processes (for example, over local
+domain sockets), and mappings at the same offset refer to the same
+memory, or the descriptor can be used to create alias mappings within
+the same process.
+
+The descriptor initially refers to a zero-length file.  Before mappings
+can be created which are backed by memory, the file size needs to be
+increased with the @code{ftruncate} function.  @xref{File Size}.
+
+The @var{flags} argument can be a combination of the following flags:
+
+@table @code
+@item MFD_CLOEXEC
+The descriptor is created with the @code{O_CLOEXEC} flag.
+
+@item MFD_ALLOW_SEALING
+The descriptor supports the addition of seals using the @code{fcntl}
+function.
+@end table
+
+The @code{memfd_create} function is specific to Linux.
+
+@end deftypefn
+
+
 @node Waiting for I/O
 @section Waiting for Input or Output
 @cindex waiting for input or output
diff --git a/support/Makefile b/support/Makefile
index 027a663000..dafb1737a4 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -109,19 +109,22 @@  libsupport-routines = \
   xpthread_once \
   xpthread_rwlock_init \
   xpthread_rwlock_rdlock \
-  xpthread_rwlock_wrlock \
   xpthread_rwlock_unlock \
+  xpthread_rwlock_wrlock \
   xpthread_rwlockattr_init \
   xpthread_rwlockattr_setkind_np \
   xpthread_sigmask \
   xpthread_spin_lock \
   xpthread_spin_unlock \
+  xreadlink \
   xrealloc \
   xrecvfrom \
   xsendto \
   xsetsockopt \
   xsocket \
   xstrdup \
+  xstrndup \
+  xunlink \
   xwaitpid \
   xwrite \
 
@@ -138,6 +141,7 @@  tests = \
   tst-support_capture_subprocess \
   tst-support_format_dns_packet \
   tst-support_record_failure \
+  tst-xreadlink \
 
 ifeq ($(run-built-tests),yes)
 tests-special = \
diff --git a/support/support.h b/support/support.h
index 4b5f04c2cc..bbba803ba1 100644
--- a/support/support.h
+++ b/support/support.h
@@ -68,6 +68,7 @@  void *xrealloc (void *p, size_t n);
 char *xasprintf (const char *format, ...)
   __attribute__ ((format (printf, 1, 2), malloc));
 char *xstrdup (const char *);
+char *xstrndup (const char *, size_t);
 
 __END_DECLS
 
diff --git a/support/support_chroot.c b/support/support_chroot.c
index f3ef551b05..f6fad18f33 100644
--- a/support/support_chroot.c
+++ b/support/support_chroot.c
@@ -46,10 +46,11 @@  support_chroot_create (struct support_chroot_configuration conf)
 {
   struct support_chroot *chroot = xmalloc (sizeof (*chroot));
 
-  chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
-  if (mkdtemp (chroot->path_chroot) == NULL)
-    FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot);
-  add_temp_file (chroot->path_chroot);
+  {
+    char *template = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
+    chroot->path_chroot = support_create_temp_directory (template);
+    free (template);
+  }
 
   /* Create the /etc directory in the chroot environment.  */
   char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);
diff --git a/support/temp_file.c b/support/temp_file.c
index fdb2477ab9..cbd54e2e17 100644
--- a/support/temp_file.c
+++ b/support/temp_file.c
@@ -86,6 +86,19 @@  create_temp_file (const char *base, char **filename)
   return fd;
 }
 
+char *
+support_create_temp_directory (const char *base)
+{
+  char *base_copy = xstrdup (base);
+  if (mkdtemp (base_copy) == NULL)
+    {
+      printf ("error: mkdtemp (\"%s\"): %m", base);
+      exit (1);
+    }
+  add_temp_file (base_copy);
+  return base_copy;
+}
+
 /* Helper functions called by the test skeleton follow.  */
 
 void
diff --git a/support/temp_file.h b/support/temp_file.h
index 6fed8df1ea..dfefe585de 100644
--- a/support/temp_file.h
+++ b/support/temp_file.h
@@ -32,6 +32,11 @@  void add_temp_file (const char *name);
    *FILENAME.  */
 int create_temp_file (const char *base, char **filename);
 
+/* Create a temporary directory and schedule it for deletion.  BASE
+   must end with the six characters "XXXXXX".  Return the name of the
+   temporary directory.  The caller should free the string.  */
+char *support_create_temp_directory (const char *base);
+
 __END_DECLS
 
 #endif /* SUPPORT_TEMP_FILE_H */
diff --git a/support/tst-xreadlink.c b/support/tst-xreadlink.c
new file mode 100644
index 0000000000..cb2c12a888
--- /dev/null
+++ b/support/tst-xreadlink.c
@@ -0,0 +1,72 @@ 
+/* Test the xreadlink function.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+
+static int
+do_test (void)
+{
+  char *dir = support_create_temp_directory ("/tmp/tst-xreadlink-XXXXXX");
+  char *symlink_name = xasprintf ("%s/symlink", dir);
+  add_temp_file (symlink_name);
+
+  /* The limit 10000 is arbitrary and simply there to prevent an
+     attempt to exhaust all available disk space.  */
+  for (int size = 1; size < 10000; ++size)
+    {
+      char *contents = xmalloc (size + 1);
+      for (int i = 0; i < size; ++i)
+        contents[i] = 'a' + (rand () % 26);
+      contents[size] = '\0';
+      if (symlink (contents, symlink_name) != 0)
+        {
+          if (errno == ENAMETOOLONG)
+            {
+              printf ("info: ENAMETOOLONG failure at %d bytes\n", size);
+              free (contents);
+              break;
+            }
+          FAIL_EXIT1 ("symlink (%d bytes): %m", size);
+        }
+
+      char *readlink_result = xreadlink (symlink_name);
+      TEST_VERIFY (strcmp (readlink_result, contents) == 0);
+      free (readlink_result);
+      xunlink (symlink_name);
+      free (contents);
+    }
+
+  /* Create an empty file to suppress the temporary file deletion
+     warning.  */
+  xclose (xopen (symlink_name, O_WRONLY | O_CREAT, 0));
+
+  free (symlink_name);
+  free (dir);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/support/xreadlink.c b/support/xreadlink.c
new file mode 100644
index 0000000000..aec58a2aa6
--- /dev/null
+++ b/support/xreadlink.c
@@ -0,0 +1,44 @@ 
+/* Error-checking, allocating wrapper for readlink.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <scratch_buffer.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <xunistd.h>
+
+char *
+xreadlink (const char *path)
+{
+  struct scratch_buffer buf;
+  scratch_buffer_init (&buf);
+
+  while (true)
+    {
+      ssize_t count = readlink (path, buf.data, buf.length);
+      if (count < 0)
+        FAIL_EXIT1 ("readlink (\"%s\"): %m", path);
+      if (count < buf.length)
+        {
+          char *result = xstrndup (buf.data, count);
+          scratch_buffer_free (&buf);
+          return result;
+        }
+      if (!scratch_buffer_grow (&buf))
+        FAIL_EXIT1 ("scratch_buffer_grow in xreadlink");
+    }
+}
diff --git a/support/xstrndup.c b/support/xstrndup.c
new file mode 100644
index 0000000000..d59a283d25
--- /dev/null
+++ b/support/xstrndup.c
@@ -0,0 +1,30 @@ 
+/* strndup with error checking.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/support.h>
+
+#include <string.h>
+
+char *
+xstrndup (const char *s, size_t length)
+{
+  char *p = strndup (s, length);
+  if (p == NULL)
+    oom_error ("strndup", length);
+  return p;
+}
diff --git a/support/xunistd.h b/support/xunistd.h
index c947bfd8fb..05c2626a7b 100644
--- a/support/xunistd.h
+++ b/support/xunistd.h
@@ -38,6 +38,11 @@  int xopen (const char *path, int flags, mode_t);
 void xstat (const char *path, struct stat64 *);
 void xmkdir (const char *path, mode_t);
 void xchroot (const char *path);
+void xunlink (const char *path);
+
+/* Read the link at PATH.  The caller should free the returned string
+   with free.  */
+char *xreadlink (const char *path);
 
 /* Close the file descriptor.  Ignore EINTR errors, but terminate the
    process on other errors.  */
diff --git a/support/xunlink.c b/support/xunlink.c
new file mode 100644
index 0000000000..f94ee118cf
--- /dev/null
+++ b/support/xunlink.c
@@ -0,0 +1,27 @@ 
+/* Error-checking wrapper for unlink.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+#include <support/xunistd.h>
+
+void
+xunlink (const char *path)
+{
+  if (unlink (path) != 0)
+    FAIL_EXIT1 ("unlink (\"%s\"): %m", path);
+}
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 0c8a009b5e..3a5515d092 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -39,7 +39,7 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  sys/klog.h \
 		  sys/user.h sys/prctl.h \
 		  sys/kd.h sys/soundcard.h sys/vt.h \
-		  sys/quota.h sys/fsuid.h \
+		  sys/quota.h sys/fsuid.h sys/memfd.h \
 		  scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \
 		  sys/raw.h sys/personality.h sys/epoll.h \
 		  bits/a.out.h sys/inotify.h sys/signalfd.h sys/eventfd.h \
@@ -50,7 +50,8 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
-	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max
+	 tst-quota tst-sync_file_range test-errno-linux tst-sysconf-iov_max \
+	 tst-memfd_create
 
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 6c9e06f4f9..992c19729f 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -166,6 +166,9 @@  libc {
   GLIBC_2.15 {
     process_vm_readv; process_vm_writev;
   }
+  GLIBC_2.27 {
+    memfd_create;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index ed598aedac..140ca28abc 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2106,6 +2106,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 4e57f36bcf..f698e1b2f4 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2017,6 +2017,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 5b70e1bfc9..8a8af3e3e4 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -107,6 +107,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 6a2500a8b3..5b81a6cd7d 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1871,6 +1871,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 9ab4e3642a..51ead9e867 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2036,6 +2036,7 @@  GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 81bb623fe8..78b4ee8d40 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1900,6 +1900,7 @@  GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 5a33b57390..d9c97779e4 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -108,6 +108,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 50a86e74fa..4acbf7eeed 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1985,6 +1985,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 250ef305c3..93f02f08ce 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2106,3 +2106,4 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 87a1dc4ad7..795e85de70 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1960,6 +1960,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index f2b35f250e..dc714057b7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1958,6 +1958,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ade654dbea..ce7bc9b175 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1956,6 +1956,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 56032c3f82..3fdd85eace 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1951,6 +1951,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index c599dd9212..3e0bcb2a5c 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2147,3 +2147,4 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 385409aa6e..375c69d9d1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1989,6 +1989,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e99cb454b5..a88172a906 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1994,6 +1994,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 173672ab5e..fa026a332c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2201,3 +2201,4 @@  GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 8a654436ab..838f395d78 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -108,6 +108,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index dbd411ceb1..41b79c496a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1989,6 +1989,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 5617784ca0..68251a0e69 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1890,6 +1890,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 0f840e6e88..bc1aae275e 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1875,6 +1875,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index bb7e1042c7..93e6d092ac 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1982,6 +1982,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 4053b0a51c..b11d6764d4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1919,6 +1919,7 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.27 strfromf128 F
 GLIBC_2.27 strtof128 F
 GLIBC_2.27 strtof128_l F
diff --git a/sysdeps/unix/sysv/linux/sys/memfd.h b/sysdeps/unix/sysv/linux/sys/memfd.h
new file mode 100644
index 0000000000..8255ecd7a4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sys/memfd.h
@@ -0,0 +1,28 @@ 
+/* memfd_create system call and constants.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MEMFD_H
+#define _SYS_MEMFD_H
+
+#include <linux/memfd.h>
+
+/* Create a new memory file descriptor.  NAME is a name for debugging.
+   FLAGS is a combination of the MFD_* constants.  */
+int memfd_create (const char *__name, unsigned int __flags);
+
+#endif /* _SYS_MEMFD_H */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 8bfb080d80..40c4fbb9ea 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -109,3 +109,4 @@  setns		EXTRA	setns		i:ii	setns
 
 process_vm_readv EXTRA	process_vm_readv i:ipipii process_vm_readv
 process_vm_writev EXTRA	process_vm_writev i:ipipii process_vm_writev
+memfd_create    EXTRA	memfd_create	i:si    memfd_create
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index 38a96d3a02..e9eb4ff7bd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2113,3 +2113,4 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 572b917d7d..8f08e909cd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2113,3 +2113,4 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index 38a96d3a02..e9eb4ff7bd 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2113,3 +2113,4 @@  GLIBC_2.26 reallocarray F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
diff --git a/sysdeps/unix/sysv/linux/tst-memfd_create.c b/sysdeps/unix/sysv/linux/tst-memfd_create.c
new file mode 100644
index 0000000000..709cf46791
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-memfd_create.c
@@ -0,0 +1,134 @@ 
+/* Test for the memfd_create system call.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <sys/syscall.h>
+
+#ifndef SYS_memfd_create
+static int
+do_test (void)
+{
+  puts ("warning: kernel headers do not support memfd_create");
+  return EXIT_UNSUPPORTED;
+}
+
+#else /* SYS_memfd_create */
+
+#include <sys/memfd.h>
+
+/* Return true if the descriptor has the FD_CLOEXEC flag set.  */
+static bool
+is_cloexec (int fd)
+{
+  int flags = fcntl (fd, F_GETFD);
+  TEST_VERIFY (flags >= 0);
+  return flags & FD_CLOEXEC;
+}
+
+/* Return the seals set on FD.  */
+static int
+get_seals (int fd)
+{
+  int flags = fcntl (fd, F_GET_SEALS);
+  TEST_VERIFY (flags >= 0);
+  return flags;
+}
+
+/* Return true if the F_SEAL_SEAL flag is set on the descriptor.  */
+static bool
+is_sealed (int fd)
+{
+  return get_seals (fd) & F_SEAL_SEAL;
+}
+
+static int
+do_test (void)
+{
+  /* Initialized by the first call to memfd_create to 0 (memfd_create
+     unsupported) or 1 (memfd_create is implemented in the kernel).
+     Subsequent iterations check that the success/failure state is
+     consistent.  */
+  int supported = -1;
+
+  for (int do_cloexec = 0; do_cloexec < 2; ++do_cloexec)
+    for (int do_sealing = 0; do_sealing < 2; ++do_sealing)
+      {
+        int flags = 0;
+        if (do_cloexec)
+          flags |= MFD_CLOEXEC;
+        if (do_sealing)
+          flags |= MFD_ALLOW_SEALING;
+        if  (test_verbose > 0)
+          printf ("info: memfd_create with flags=0x%x\n", flags);
+        int fd = memfd_create ("tst-memfd_create", flags);
+        if (fd < 0)
+          {
+            if (errno == ENOSYS)
+              {
+                if (supported < 0)
+                  {
+                    supported = 0;
+                    continue;
+                  }
+                TEST_VERIFY (supported == 0);
+                continue;
+              }
+            else
+              FAIL_EXIT1 ("memfd_create: %m");
+          }
+        if (supported < 0)
+          supported = 1;
+        TEST_VERIFY (supported > 0);
+
+        char *fd_path = xasprintf ("/proc/self/fd/%d", fd);
+        char *link = xreadlink (fd_path);
+        if (test_verbose > 0)
+          printf ("info: memfd link: %s\n", link);
+        TEST_VERIFY (strcmp (link, "memfd:tst-memfd_create (deleted)"));
+        TEST_VERIFY (is_cloexec (fd) == do_cloexec);
+        TEST_VERIFY (is_sealed (fd) == !do_sealing);
+        if (do_sealing)
+          {
+            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_WRITE) == 0);
+            TEST_VERIFY (!is_sealed (fd));
+            TEST_VERIFY (get_seals (fd) & F_SEAL_WRITE);
+            TEST_VERIFY (fcntl (fd, F_ADD_SEALS, F_SEAL_SEAL) == 0);
+            TEST_VERIFY (is_sealed (fd));
+          }
+        xclose (fd);
+        free (fd_path);
+        free (link);
+      }
+
+  if (supported == 0)
+    return EXIT_UNSUPPORTED;
+  return 0;
+}
+
+#endif /* SYS_memfd_create */
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index b83d25c2e3..0a4f7797ac 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1877,6 +1877,7 @@  GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index cba1d59057..23f6a91429 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2120,3 +2120,4 @@  GLIBC_2.26 wcstof128_l F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 glob F
 GLIBC_2.27 glob64 F
+GLIBC_2.27 memfd_create F