unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: enh <enh@google.com>
To: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Cc: libc-alpha@sourceware.org, Stas Sergeev <stsp@users.sourceforge.net>
Subject: Re: [PATCH] linux: Add openat2 (BZ 31664)
Date: Thu, 25 Apr 2024 07:10:55 -0700	[thread overview]
Message-ID: <CAJgzZorbKuf1b+cqtjjd1onStPrtyny5daPdEJWinHBUJG-6hQ@mail.gmail.com> (raw)
In-Reply-To: <50263380-712c-4348-a249-3ca6edd2d833@linaro.org>

On Thu, Apr 25, 2024 at 7:01 AM Adhemerval Zanella Netto
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 24/04/24 18:18, enh wrote:
> > On Wed, Apr 24, 2024 at 11:05 AM Adhemerval Zanella Netto
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >> That's a good question, since we currently do not export any kernel interface
> >> which this new struct/size argument passing (we do use clone3, but it is
> >> just internally). For a libc/kernel interface, it should not matter; but from
> >> a libc exported symbol we indeed need to be more careful.
> >>
> >> From a glibc perpectiveI think we will need to *not* include kernel UAPI header,
> >> remove the size from the wrapper, and add some slack size on open_how for
> >> future extension.  It makes open_how extensions to not require new symbol
> >> version in the near future (similar to what was done for statx).
> >
> > i think statx did that _in uapi_, no? there's already padding
> > upstream. (that's a much better way to do these things from a libc
> > perspective; if someone talks to the kernel folks, it's worth trying
> > to encourage them to do more of that, and less of the openat2() or
> > sched_setattr().)
>
> Yes, the statx added some spare fields because it does not have the extra
> size parameter and an statx extension that extends further will require
> another syscall (this is the same for sched_setattr). The openat2 approach
> is not bad, it solves this issue.

it is bad, because it solves the _kernel_ problem by creating a
userspace problem.

(not versioning the _syscall_ is fine, as long as you version the
_struct_ -- and we have a void* and size_t in the libc api -- but not
versioning either just pushes new problems onto userspace. userspace
would be better off with multiple syscalls!)

> This new kernel interface also solves another other historical problem:
> it allows sizes larger than current supported as long extra fields are
> zeroed and returns EINVAL otherwise.  So I think is unlikely kernel will
> add spare field on open_how, it only ads extra complexity for the kABI.
>
> So for glibc I think it would still be better to add the spare fields,
> mainly to avoid the need to possible add new symbol versions if it requires
> to pick the struct for a eventual struct extension.
>
> >
> >> It would make the libc and kernel version not easily interchangeable (which
> >> some users do want on some cases).
> >>
> >> On 24/04/24 14:42, enh wrote:
> >>> doesn't glibc worry about types like this, where the size can change?
> >>> that presents a problem for code passing those types around. do you
> >>> require that all the code in a process be compiled with the exact same
> >>> headers?
> >>>
> >>> On Wed, Apr 24, 2024 at 10:38 AM Adhemerval Zanella
> >>> <adhemerval.zanella@linaro.org> wrote:
> >>>>
> >>>> It was added on Linux 5.6, as an extension of openat.  Different than
> >>>> other open-like functions, the kernel only provides the LFS variant (so
> >>>> files larger than 4GB always succeed, as other functions with offset
> >>>> larger than off_t).  Similar to other open functions, the new symbol is
> >>>> a cancellable entrypoint.
> >>>>
> >>>> The test case added only stresses some of the syscalls provided
> >>>> functionalities and it is based on an existent kernel self-test.  Since
> >>>> the prototype does not use variadic arguments, there is no need to add a
> >>>> fortify wrapper to catch wrong usages.
> >>>>
> >>>> Checked on x86_64-linux-gnu.
> >>>> ---
> >>>>  NEWS                                          |   4 +
> >>>>  sysdeps/unix/sysv/linux/Makefile              |  14 +
> >>>>  sysdeps/unix/sysv/linux/Versions              |   3 +
> >>>>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
> >>>>  sysdeps/unix/sysv/linux/alpha/libc.abilist    |   1 +
> >>>>  sysdeps/unix/sysv/linux/arc/libc.abilist      |   1 +
> >>>>  sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   1 +
> >>>>  sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   1 +
> >>>>  sysdeps/unix/sysv/linux/bits/fcntl-linux.h    |  22 ++
> >>>>  sysdeps/unix/sysv/linux/bits/openat2.h        |  61 +++++
> >>>>  sysdeps/unix/sysv/linux/csky/libc.abilist     |   1 +
> >>>>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
> >>>>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
> >>>>  .../sysv/linux/loongarch/lp64/libc.abilist    |   1 +
> >>>>  .../sysv/linux/m68k/coldfire/libc.abilist     |   1 +
> >>>>  .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   1 +
> >>>>  .../sysv/linux/microblaze/be/libc.abilist     |   1 +
> >>>>  .../sysv/linux/microblaze/le/libc.abilist     |   1 +
> >>>>  .../sysv/linux/mips/mips32/fpu/libc.abilist   |   1 +
> >>>>  .../sysv/linux/mips/mips32/nofpu/libc.abilist |   1 +
> >>>>  .../sysv/linux/mips/mips64/n32/libc.abilist   |   1 +
> >>>>  .../sysv/linux/mips/mips64/n64/libc.abilist   |   1 +
> >>>>  sysdeps/unix/sysv/linux/nios2/libc.abilist    |   1 +
> >>>>  sysdeps/unix/sysv/linux/openat2.c             |  29 ++
> >>>>  sysdeps/unix/sysv/linux/or1k/libc.abilist     |   1 +
> >>>>  .../linux/powerpc/powerpc32/fpu/libc.abilist  |   1 +
> >>>>  .../powerpc/powerpc32/nofpu/libc.abilist      |   1 +
> >>>>  .../linux/powerpc/powerpc64/be/libc.abilist   |   1 +
> >>>>  .../linux/powerpc/powerpc64/le/libc.abilist   |   1 +
> >>>>  .../unix/sysv/linux/riscv/rv32/libc.abilist   |   1 +
> >>>>  .../unix/sysv/linux/riscv/rv64/libc.abilist   |   1 +
> >>>>  .../unix/sysv/linux/s390/s390-32/libc.abilist |   1 +
> >>>>  .../unix/sysv/linux/s390/s390-64/libc.abilist |   1 +
> >>>>  sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   1 +
> >>>>  sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   1 +
> >>>>  .../sysv/linux/sparc/sparc32/libc.abilist     |   1 +
> >>>>  .../sysv/linux/sparc/sparc64/libc.abilist     |   1 +
> >>>>  sysdeps/unix/sysv/linux/tst-openat2-consts.py |  63 +++++
> >>>>  sysdeps/unix/sysv/linux/tst-openat2.c         | 259 ++++++++++++++++++
> >>>>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
> >>>>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
> >>>>  41 files changed, 488 insertions(+)
> >>>>  create mode 100644 sysdeps/unix/sysv/linux/bits/openat2.h
> >>>>  create mode 100644 sysdeps/unix/sysv/linux/openat2.c
> >>>>  create mode 100755 sysdeps/unix/sysv/linux/tst-openat2-consts.py
> >>>>  create mode 100644 sysdeps/unix/sysv/linux/tst-openat2.c
> >>>>
> >>>> diff --git a/NEWS b/NEWS
> >>>> index cf6078cf20..eaaa02cb4e 100644
> >>>> --- a/NEWS
> >>>> +++ b/NEWS
> >>>> @@ -26,6 +26,10 @@ Major new features:
> >>>>    more extensive verification tests for AT_SECURE programs and not meant to
> >>>>    be a security feature.
> >>>>
> >>>> +* On Linux, the openat2 function has been added.  It is an extension of
> >>>> +  openat and provides a superset of its functionality.  It is supported only
> >>>> +  in LFS mode and as other open like it is a cancellable entrypoint.
> >>>> +
> >>>>  Deprecated and removed features, and other changes affecting compatibility:
> >>>>
> >>>>  * Architectures which use a 32-bit seconds-since-epoch field in struct
> >>>> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> >>>> index 415aa1f14d..4ae8ec6dc6 100644
> >>>> --- a/sysdeps/unix/sysv/linux/Makefile
> >>>> +++ b/sysdeps/unix/sysv/linux/Makefile
> >>>> @@ -133,6 +133,7 @@ sysdep_headers += \
> >>>>    bits/mman-linux.h \
> >>>>    bits/mman-map-flags-generic.h \
> >>>>    bits/mman-shared.h \
> >>>> +  bits/openat2.h \
> >>>>    bits/procfs-extra.h \
> >>>>    bits/procfs-id.h \
> >>>>    bits/procfs-prregset.h \
> >>>> @@ -591,6 +592,7 @@ sysdep_routines += \
> >>>>    internal_statvfs \
> >>>>    open64_nocancel \
> >>>>    open_nocancel \
> >>>> +  openat2 \
> >>>>    openat64_nocancel \
> >>>>    openat_nocancel \
> >>>>    pread64_nocancel \
> >>>> @@ -611,7 +613,19 @@ tests += \
> >>>>    tst-fallocate64 \
> >>>>    tst-getcwd-smallbuff \
> >>>>    tst-o_path-locks \
> >>>> +  tst-openat2 \
> >>>>    # tests
> >>>> +
> >>>> +tests-special += \
> >>>> +  $(objpfx)tst-openat2-consts.out \
> >>>> +  # tests-special
> >>>> +$(objpfx)tst-openat2-consts.out: ../sysdeps/unix/sysv/linux/tst-openat2-consts.py
> >>>> +       $(sysdeps-linux-python) \
> >>>> +         ../sysdeps/unix/sysv/linux/tst-openat2-consts.py \
> >>>> +           $(sysdeps-linux-python-cc) \
> >>>> +         < /dev/null > $@ 2>&1; $(evaluate-test)
> >>>> +$(objpfx)tst-openat2-consts.out: $(sysdeps-linux-python-deps)
> >>>> +
> >>>>  endif
> >>>>
> >>>>  ifeq ($(subdir),elf)
> >>>> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> >>>> index 268ba1b6ac..65da2b617a 100644
> >>>> --- a/sysdeps/unix/sysv/linux/Versions
> >>>> +++ b/sysdeps/unix/sysv/linux/Versions
> >>>> @@ -328,6 +328,9 @@ libc {
> >>>>      posix_spawnattr_getcgroup_np;
> >>>>      posix_spawnattr_setcgroup_np;
> >>>>    }
> >>>> +  GLIBC_2.40 {
> >>>> +    openat2;
> >>>> +  }
> >>>>    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 68eeca1c08..0b9bd8ae62 100644
> >>>> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> >>>> @@ -2748,3 +2748,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> >>>> index 34c187b721..c0bd27d617 100644
> >>>> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> >>>> @@ -3095,6 +3095,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> >>>> index 916c18ea94..965438e7a7 100644
> >>>> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> >>>> @@ -2509,3 +2509,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> >>>> index ea95de282a..e69ed8c903 100644
> >>>> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> >>>> @@ -2801,6 +2801,7 @@ GLIBC_2.4 xdrstdio_create F
> >>>>  GLIBC_2.4 xencrypt F
> >>>>  GLIBC_2.4 xprt_register F
> >>>>  GLIBC_2.4 xprt_unregister F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> >>>> index 1cdbc983e1..70fd425869 100644
> >>>> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> >>>> @@ -2798,6 +2798,7 @@ GLIBC_2.4 xdrstdio_create F
> >>>>  GLIBC_2.4 xencrypt F
> >>>>  GLIBC_2.4 xprt_register F
> >>>>  GLIBC_2.4 xprt_unregister F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
> >>>> index 628612b885..279aa2b8eb 100644
> >>>> --- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
> >>>> +++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
> >>>> @@ -451,6 +451,28 @@ extern int name_to_handle_at (int __dfd, const char *__name,
> >>>>  extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle,
> >>>>                               int __flags);
> >>>>
> >>>> +#ifdef __has_include
> >>>> +# if __has_include ("linux/openat2.h")
> >>>> +#  include "linux/openat2.h"
> >>>> +#  define __glibc_has_open_how 1
> >>>> +# endif
> >>>> +#endif
> >>>> +
> >>>> +#include <bits/openat2.h>
> >>>> +
> >>>> +/* Similar to `openat' but the arguments are packed on HOW with the size
> >>>> +   USIZE.  If flags and mode from HOW are non-zero, then openat2 operates
> >>>> +   like openat.
> >>>> +
> >>>> +   Unlike openat2, unknown or invalid flags result in an error (EINVAL),
> >>>> +   rather than being ignored.  The mode must be zero unless one O_CREAT
> >>>> +   or O_TMPFILE are set.
> >>>> +
> >>>> +   The kernel does not support legacy non-LFS interface.  */
> >>>> +extern int openat2 (int __dfd, const char *__filename, struct open_how *__how,
> >>>> +                   size_t __usize)
> >>>> +     __nonnull ((2, 3));
> >>>> +
> >>>>  #endif /* use GNU */
> >>>>
> >>>>  __END_DECLS
> >>>> diff --git a/sysdeps/unix/sysv/linux/bits/openat2.h b/sysdeps/unix/sysv/linux/bits/openat2.h
> >>>> new file mode 100644
> >>>> index 0000000000..a07984dace
> >>>> --- /dev/null
> >>>> +++ b/sysdeps/unix/sysv/linux/bits/openat2.h
> >>>> @@ -0,0 +1,61 @@
> >>>> +/* openat2 definition.  Linux specific.
> >>>> +   Copyright (C) 2024 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
> >>>> +   <https://www.gnu.org/licenses/>.  */
> >>>> +
> >>>> +#ifndef        _FCNTL_H
> >>>> +# error "Never use <bits/openat2.h> directly; include <fcntl.h> instead."
> >>>> +#endif
> >>>> +
> >>>> +#ifndef __glibc_has_open_how
> >>>> +/* Arguments for how openat2 should open the target path.  */
> >>>> +struct open_how
> >>>> +{
> >>>> +  __uint64_t flags;
> >>>> +  __uint64_t mode;
> >>>> +  __uint64_t resolve;
> >>>> +};
> >>>> +#endif
> >>>> +
> >>>> +/* how->resolve flags for openat2. */
> >>>> +#ifndef RESOLVE_NO_XDEV
> >>>> +# define RESOLVE_NO_XDEV       0x01 /* Block mount-point crossings
> >>>> +                                       (includes bind-mounts).  */
> >>>> +#endif
> >>>> +#ifndef RESOLVE_NO_MAGICLINKS
> >>>> +# define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style
> >>>> +                                       "magic-links".  */
> >>>> +#endif
> >>>> +#ifndef RESOLVE_NO_SYMLINKS
> >>>> +# define RESOLVE_NO_SYMLINKS   0x04 /* Block traversal through all symlinks
> >>>> +                                       (implies OEXT_NO_MAGICLINKS).  */
> >>>> +#endif
> >>>> +#ifndef RESOLVE_BENEATH
> >>>> +# define RESOLVE_BENEATH       0x08 /* Block "lexical" trickery like
> >>>> +                                       "..", symlinks, and absolute
> >>>> +                                       paths which escape the dirfd.  */
> >>>> +#endif
> >>>> +#ifndef RESOLVE_IN_ROOT
> >>>> +# define RESOLVE_IN_ROOT       0x10 /* Make all jumps to "/" and ".."
> >>>> +                                       be scoped inside the dirfd
> >>>> +                                       (similar to chroot).  */
> >>>> +#endif
> >>>> +#ifndef RESOLVE_CACHED
> >>>> +# define RESOLVE_CACHED                0x20 /* Only complete if resolution can be
> >>>> +                                       completed through cached lookup. May
> >>>> +                                       return -EAGAIN if that's not
> >>>> +                                       possible.  */
> >>>> +#endif
> >>>> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> >>>> index 96d45961e2..c81ea43dc1 100644
> >>>> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> >>>> @@ -2785,3 +2785,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> >>>> index fbcd60c2b3..23eec25d8a 100644
> >>>> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> >>>> @@ -2821,6 +2821,7 @@ GLIBC_2.4 sys_errlist D 0x400
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> >>>> index c989b433c0..4ce2afb147 100644
> >>>> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> >>>> @@ -3005,6 +3005,7 @@ GLIBC_2.4 sys_errlist D 0x210
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> >>>> index 0023ec1fa1..be76251b28 100644
> >>>> --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> >>>> @@ -2269,3 +2269,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> >>>> index d9bd6a9b56..5ff3db5035 100644
> >>>> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> >>>> @@ -2781,6 +2781,7 @@ GLIBC_2.4 xdrstdio_create F
> >>>>  GLIBC_2.4 xencrypt F
> >>>>  GLIBC_2.4 xprt_register F
> >>>>  GLIBC_2.4 xprt_unregister F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> >>>> index 439796d693..39645248af 100644
> >>>> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> >>>> @@ -2948,6 +2948,7 @@ GLIBC_2.4 sys_errlist D 0x210
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> >>>> index 1069d3252c..2f917724de 100644
> >>>> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> >>>> @@ -2834,3 +2834,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> >>>> index 17abe08c8b..6cc64f97b5 100644
> >>>> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> >>>> @@ -2831,3 +2831,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> >>>> index 799e508950..ae5b95bc76 100644
> >>>> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> >>>> @@ -2909,6 +2909,7 @@ GLIBC_2.4 renameat F
> >>>>  GLIBC_2.4 symlinkat F
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> >>>> index 1c10996cbc..434e997937 100644
> >>>> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> >>>> @@ -2907,6 +2907,7 @@ GLIBC_2.4 renameat F
> >>>>  GLIBC_2.4 symlinkat F
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> >>>> index 03d9655f26..5dc2996fcc 100644
> >>>> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> >>>> @@ -2915,6 +2915,7 @@ GLIBC_2.4 renameat F
> >>>>  GLIBC_2.4 symlinkat F
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> >>>> index 05e402ed30..865dc5e7f1 100644
> >>>> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> >>>> @@ -2817,6 +2817,7 @@ GLIBC_2.4 renameat F
> >>>>  GLIBC_2.4 symlinkat F
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> >>>> index 3aa81766aa..12775fdad5 100644
> >>>> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> >>>> @@ -2873,3 +2873,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/openat2.c b/sysdeps/unix/sysv/linux/openat2.c
> >>>> new file mode 100644
> >>>> index 0000000000..a2b134bab0
> >>>> --- /dev/null
> >>>> +++ b/sysdeps/unix/sysv/linux/openat2.c
> >>>> @@ -0,0 +1,29 @@
> >>>> +/* Linux openat2 syscall implementation.
> >>>> +   Copyright (C) 2024 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
> >>>> +   <https://www.gnu.org/licenses/>.  */
> >>>> +
> >>>> +#include <fcntl.h>
> >>>> +#include <bits/openat2.h>
> >>>> +#include <sysdep-cancel.h>
> >>>> +
> >>>> +int
> >>>> +__openat2 (int dfd, const char *filename, struct open_how *how,
> >>>> +          size_t usize)
> >>>> +{
> >>>> +  return SYSCALL_CANCEL (openat2, dfd, filename, how, usize);
> >>>> +}
> >>>> +weak_alias (__openat2, openat2)
> >>>> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> >>>> index c40c843aaf..2835436011 100644
> >>>> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> >>>> @@ -2255,3 +2255,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> >>>> index 9714305608..3b70a56944 100644
> >>>> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> >>>> @@ -3138,6 +3138,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> >>>> index 0beb52c542..677c9a75de 100644
> >>>> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> >>>> @@ -3183,6 +3183,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> >>>> index cfc2ebd3ec..10fc3c89dc 100644
> >>>> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> >>>> @@ -2892,6 +2892,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> >>>> index 8c9efc5a16..713fa1d1c8 100644
> >>>> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> >>>> @@ -2968,3 +2968,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> >>>> index 6397a9cb91..550ba877ef 100644
> >>>> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> >>>> @@ -2512,3 +2512,4 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>>  GLIBC_2.40 __riscv_hwprobe F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> >>>> index 71bbf94f66..8bf9f309b7 100644
> >>>> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> >>>> @@ -2712,3 +2712,4 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>>  GLIBC_2.40 __riscv_hwprobe F
> >>>> +GLIBC_2.40 openat2 F
> >>>> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> >>>> index a7467e2850..08bc3d6f8b 100644
> >>>> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> >>>> @@ -3136,6 +3136,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> >>>> index fd1cb2972d..e25afff581 100644
> >>>> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> >>>> @@ -2929,6 +2929,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> >>>> index ff6e6b1a13..499de50ee0 100644
> >>>> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> >>>> @@ -2828,6 +2828,7 @@ GLIBC_2.4 sys_errlist D 0x210
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> >>>> index 449d92bbc5..bdd9c600f0 100644
> >>>> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> >>>> @@ -2825,6 +2825,7 @@ GLIBC_2.4 sys_errlist D 0x210
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> >>>> index e615be759a..b20dd43d47 100644
> >>>> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> >>>> @@ -3157,6 +3157,7 @@ GLIBC_2.4 wcstold F
> >>>>  GLIBC_2.4 wcstold_l F
> >>>>  GLIBC_2.4 wprintf F
> >>>>  GLIBC_2.4 wscanf F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> >>>> index bd36431dd7..19981aa981 100644
> >>>> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> >>>> @@ -2793,6 +2793,7 @@ GLIBC_2.4 sys_errlist D 0x430
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/tst-openat2-consts.py b/sysdeps/unix/sysv/linux/tst-openat2-consts.py
> >>>> new file mode 100755
> >>>> index 0000000000..1623fafd94
> >>>> --- /dev/null
> >>>> +++ b/sysdeps/unix/sysv/linux/tst-openat2-consts.py
> >>>> @@ -0,0 +1,63 @@
> >>>> +#!/usr/bin/python3
> >>>> +# Test that glibc's sys/openat2.h constants match the kernel's.
> >>>> +# Copyright (C) 2024 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
> >>>> +# <https://www.gnu.org/licenses/>.
> >>>> +
> >>>> +import argparse
> >>>> +import sys
> >>>> +
> >>>> +import glibcextract
> >>>> +import glibcsyscalls
> >>>> +
> >>>> +
> >>>> +def main():
> >>>> +    """The main entry point."""
> >>>> +    parser = argparse.ArgumentParser(
> >>>> +        description="Test that glibc's sys/openat2.h constants "
> >>>> +        "match the kernel's.")
> >>>> +    parser.add_argument('--cc', metavar='CC',
> >>>> +                        help='C compiler (including options) to use')
> >>>> +    args = parser.parse_args()
> >>>> +
> >>>> +    if glibcextract.compile_c_snippet(
> >>>> +            '#include <linux/openat2.h>',
> >>>> +            args.cc).returncode != 0:
> >>>> +        sys.exit (77)
> >>>> +
> >>>> +    linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
> >>>> +    # Constants in glibc were updated to match Linux v6.8.  When glibc
> >>>> +    # constants are updated this value should be updated to match the
> >>>> +    # released kernel version from which the constants were taken.
> >>>> +    linux_version_glibc = (6, 8)
> >>>> +    def check(cte, exclude=None):
> >>>> +        return glibcextract.compare_macro_consts(
> >>>> +                '#define _FCNTL_H\n'
> >>>> +                '#include <stdint.h>\n'
> >>>> +                '#include <bits/openat2.h>\n',
> >>>> +                '#include <asm/fcntl.h>\n'
> >>>> +                '#include <linux/openat2.h>\n',
> >>>> +                args.cc,
> >>>> +                cte,
> >>>> +                exclude,
> >>>> +                linux_version_glibc > linux_version_headers,
> >>>> +                linux_version_headers > linux_version_glibc)
> >>>> +
> >>>> +    status = check('RESOLVE.*')
> >>>> +    sys.exit(status)
> >>>> +
> >>>> +if __name__ == '__main__':
> >>>> +    main()
> >>>> diff --git a/sysdeps/unix/sysv/linux/tst-openat2.c b/sysdeps/unix/sysv/linux/tst-openat2.c
> >>>> new file mode 100644
> >>>> index 0000000000..d0c26f2bce
> >>>> --- /dev/null
> >>>> +++ b/sysdeps/unix/sysv/linux/tst-openat2.c
> >>>> @@ -0,0 +1,259 @@
> >>>> +/* Linux openat2 tests.
> >>>> +   Copyright (C) 2024 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
> >>>> +   <https://www.gnu.org/licenses/>.  */
> >>>> +
> >>>> +/* openat2 always return a file descriptor in LFS mode.  */
> >>>> +#define _FILE_OFFSET_BITS 64
> >>>> +
> >>>> +#include <array_length.h>
> >>>> +#include <errno.h>
> >>>> +#include <fcntl.h>
> >>>> +#include <stdint.h>
> >>>> +#include <support/check.h>
> >>>> +#include <support/temp_file.h>
> >>>> +#include <support/xunistd.h>
> >>>> +
> >>>> +static int dir_fd;
> >>>> +
> >>>> +static void
> >>>> +do_prepare (int argc, char *argv[])
> >>>> +{
> >>>> +  char *temp_dir = support_create_temp_directory ("tst-openat2");
> >>>> +  dir_fd = xopen (temp_dir, O_RDONLY | O_DIRECTORY, 0);
> >>>> +}
> >>>> +#define PREPARE do_prepare
> >>>> +
> >>>> +static int
> >>>> +do_test_struct (void)
> >>>> +{
> >>>> +  static struct struct_test
> >>>> +  {
> >>>> +    struct open_how_ext
> >>>> +    {
> >>>> +      struct open_how inner;
> >>>> +      int extra1;
> >>>> +      int extra2;
> >>>> +      int extra3;
> >>>> +    } arg;
> >>>> +    size_t size;
> >>>> +    int err;
> >>>> +  } tests[] =
> >>>> +  {
> >>>> +    {
> >>>> +      /* Zero size.  */
> >>>> +      .arg.inner.flags = O_RDONLY,
> >>>> +      .size = 0,
> >>>> +      .err = EINVAL,
> >>>> +    },
> >>>> +    {
> >>>> +      /* Normal struct.  */
> >>>> +      .arg.inner.flags = O_RDONLY,
> >>>> +      .size = sizeof (struct open_how),
> >>>> +    },
> >>>> +    {
> >>>> +      /* Larger struct, zeroed out the unused values.  */
> >>>> +      .arg.inner.flags = O_RDONLY,
> >>>> +      .size = sizeof (struct open_how_ext),
> >>>> +    },
> >>>> +    {
> >>>> +      /* Larger struct, non-zeroed out the unused values.  */
> >>>> +      .arg.inner.flags = O_RDONLY,
> >>>> +      .arg.extra1 = 0xdeadbeef,
> >>>> +      .size = sizeof (struct open_how_ext),
> >>>> +      .err = E2BIG,
> >>>> +    },
> >>>> +    {
> >>>> +      /* Larger struct, non-zeroed out the unused values.  */
> >>>> +      .arg.inner.flags = O_RDONLY,
> >>>> +      .arg.extra2 = 0xdeadbeef,
> >>>> +      .size = sizeof (struct open_how_ext),
> >>>> +      .err = E2BIG,
> >>>> +    },
> >>>> +  };
> >>>> +
> >>>> +  for (struct struct_test *t = tests; t != array_end (tests); t++)
> >>>> +    {
> >>>> +      int fd = openat2 (AT_FDCWD, ".", (struct open_how *) &t->arg, t->size);
> >>>> +      if (fd == -1 && errno == ENOSYS)
> >>>> +       FAIL_UNSUPPORTED ("openat2 is not supported by the kernel");
> >>>> +
> >>>> +      if (t->err != 0)
> >>>> +       {
> >>>> +         TEST_COMPARE (fd, -1);
> >>>> +         TEST_COMPARE (errno, t->err);
> >>>> +       }
> >>>> +      else
> >>>> +       TEST_VERIFY (fd >= 0);
> >>>> +    }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int
> >>>> +do_test_flags (void)
> >>>> +{
> >>>> +  static struct flag_test
> >>>> +  {
> >>>> +    struct open_how how;
> >>>> +    int err;
> >>>> +  } tests[] =
> >>>> +  {
> >>>> +    /* O_TMPFILE is incompatible with O_PATH and O_CREAT.  */
> >>>> +    { .how.flags = O_TMPFILE | O_PATH | O_RDWR, .err = EINVAL },
> >>>> +    { .how.flags = O_TMPFILE | O_CREAT | O_RDWR, .err = EINVAL },
> >>>> +
> >>>> +    /* O_PATH only permits certain other flags to be set ...  */
> >>>> +    { .how.flags = O_PATH | O_CLOEXEC },
> >>>> +    { .how.flags = O_PATH | O_DIRECTORY },
> >>>> +    { .how.flags = O_PATH | O_NOFOLLOW },
> >>>> +    /* ... and others are absolutely not permitted. */
> >>>> +    { .how.flags = O_PATH | O_RDWR, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH | O_CREAT, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH | O_EXCL, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH | O_NOCTTY, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH | O_DIRECT, .err = EINVAL },
> >>>> +
> >>>> +    /* ->mode must only be set with O_{CREAT,TMPFILE}. */
> >>>> +    { .how.flags = O_RDONLY, .how.mode = 0600, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH,   .how.mode = 0600, .err = EINVAL },
> >>>> +    { .how.flags = O_CREAT,  .how.mode = 0600 },
> >>>> +    { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0600 },
> >>>> +    /* ->mode must only contain 0777 bits. */
> >>>> +    { .how.flags = O_CREAT, .how.mode = 0xFFFF, .err = EINVAL },
> >>>> +    { .how.flags = O_CREAT, .how.mode = 0xC000000000000000ULL, .err = EINVAL },
> >>>> +    { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0x1337, .err = EINVAL },
> >>>> +    { .how.flags = O_TMPFILE | O_RDWR, .how.mode = 0x0000A00000000000ULL,
> >>>> +      .err = EINVAL },
> >>>> +
> >>>> +    /* ->resolve flags must not conflict. */
> >>>> +    { .how.flags = O_RDONLY,
> >>>> +      .how.resolve = RESOLVE_BENEATH | RESOLVE_IN_ROOT,
> >>>> +      .err = EINVAL },
> >>>> +
> >>>> +    /* ->resolve must only contain RESOLVE_* flags.  */
> >>>> +    { .how.flags = O_RDONLY,
> >>>> +      .how.resolve = 0x1337, .err = EINVAL },
> >>>> +    { .how.flags = O_CREAT,
> >>>> +      .how.resolve = 0x1337, .err = EINVAL },
> >>>> +    { .how.flags = O_TMPFILE | O_RDWR,
> >>>> +      .how.resolve = 0x1337, .err = EINVAL },
> >>>> +    { .how.flags = O_PATH,
> >>>> +      .how.resolve = 0x1337, .err = EINVAL },
> >>>> +
> >>>> +    /* currently unknown upper 32 bit rejected.  */
> >>>> +    { .how.flags = O_RDONLY | (1ULL << 63),
> >>>> +      .how.resolve = 0, .err = EINVAL },
> >>>> +  };
> >>>> +
> >>>> +  for (struct flag_test *t = tests; t != array_end (tests); t++)
> >>>> +    {
> >>>> +      char *path;
> >>>> +      if (t->how.flags & O_CREAT)
> >>>> +       {
> >>>> +         int temp_fd = create_temp_file ("tst-openat2.", &path);
> >>>> +         TEST_VERIFY_EXIT (temp_fd != -1);
> >>>> +         xunlink (path);
> >>>> +       }
> >>>> +      else
> >>>> +       path = (char *) ".";
> >>>> +
> >>>> +      int fd = openat2 (AT_FDCWD, path, &t->how, sizeof (struct open_how));
> >>>> +      if (fd != 0 && errno == EOPNOTSUPP)
> >>>> +       {
> >>>> +         /* Skip the testcase if FS does not support the operation (e.g.
> >>>> +            valid O_TMPFILE on NFS).  */
> >>>> +         continue;
> >>>> +       }
> >>>> +
> >>>> +      if (t->err != 0)
> >>>> +       {
> >>>> +         TEST_COMPARE (fd, -1);
> >>>> +         TEST_COMPARE (errno, t->err);
> >>>> +       }
> >>>> +      else
> >>>> +       TEST_VERIFY (fd >= 0);
> >>>> +    }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int
> >>>> +do_test_basic (void)
> >>>> +{
> >>>> +  int fd;
> >>>> +
> >>>> +  fd = openat2 (dir_fd,
> >>>> +               "some-file",
> >>>> +               &(struct open_how)
> >>>> +               {
> >>>> +                 .flags = O_CREAT|O_RDWR|O_EXCL,
> >>>> +                 .mode = 0666,
> >>>> +               },
> >>>> +               sizeof (struct open_how));
> >>>> +  TEST_VERIFY (fd != -1);
> >>>> +
> >>>> +  xwrite (fd, "hello", 5);
> >>>> +
> >>>> +  /* Before closing the file, try using this file descriptor to open
> >>>> +     another file.  This must fail.  */
> >>>> +  {
> >>>> +    int fd2 = openat2 (fd,
> >>>> +                      "should-not-work",
> >>>> +                      &(struct open_how)
> >>>> +                      {
> >>>> +                        .flags = O_CREAT|O_RDWR|O_EXCL,
> >>>> +                        .mode = 0666,
> >>>> +                      },
> >>>> +                      sizeof (struct open_how));
> >>>> +    TEST_COMPARE (fd2, -1);
> >>>> +    TEST_COMPARE (errno, ENOTDIR);
> >>>> +  }
> >>>> +
> >>>> +  /* Remove the created file.  */
> >>>> +  int cwdfd = xopen (".", O_RDONLY | O_DIRECTORY, 0);
> >>>> +  TEST_COMPARE (fchdir (dir_fd), 0);
> >>>> +  xunlink ("some-file");
> >>>> +  TEST_COMPARE (fchdir (cwdfd), 0);
> >>>> +
> >>>> +  xclose (dir_fd);
> >>>> +  xclose (cwdfd);
> >>>> +
> >>>> +  fd = openat2 (dir_fd,
> >>>> +               "some-file",
> >>>> +               &(struct open_how)
> >>>> +               {
> >>>> +                 .flags = O_CREAT|O_RDWR|O_EXCL,
> >>>> +                 .mode = 0666,
> >>>> +               },
> >>>> +               sizeof (struct open_how));
> >>>> +  TEST_COMPARE (fd, -1);
> >>>> +  TEST_COMPARE (errno, EBADF);
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int
> >>>> +do_test (void)
> >>>> +{
> >>>> +  do_test_struct ();
> >>>> +  do_test_flags ();
> >>>> +  do_test_basic ();
> >>>> +
> >>>> +  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 aea7848ed6..a7f177c8a8 100644
> >>>> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> >>>> @@ -2744,6 +2744,7 @@ GLIBC_2.4 sys_errlist D 0x420
> >>>>  GLIBC_2.4 sys_nerr D 0x4
> >>>>  GLIBC_2.4 unlinkat F
> >>>>  GLIBC_2.4 unshare F
> >>>> +GLIBC_2.40 openat2 F
> >>>>  GLIBC_2.5 __readlinkat_chk F
> >>>>  GLIBC_2.5 inet6_opt_append F
> >>>>  GLIBC_2.5 inet6_opt_find F
> >>>> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> >>>> index 4ab3681914..00dfc8f1e7 100644
> >>>> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> >>>> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> >>>> @@ -2763,3 +2763,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ul F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_ull F
> >>>>  GLIBC_2.39 stdc_trailing_zeros_us F
> >>>> +GLIBC_2.40 openat2 F
> >>>> --
> >>>> 2.34.1
> >>>>

  reply	other threads:[~2024-04-25 14:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-24 17:38 [PATCH] linux: Add openat2 (BZ 31664) Adhemerval Zanella
2024-04-24 17:42 ` enh
2024-04-24 18:05   ` Adhemerval Zanella Netto
2024-04-24 21:18     ` enh
2024-04-25 14:00       ` Adhemerval Zanella Netto
2024-04-25 14:10         ` enh [this message]
2024-04-25 16:10           ` Adhemerval Zanella Netto
2024-04-29 13:38 ` Florian Weimer
2024-05-01 14:14   ` Adhemerval Zanella Netto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJgzZorbKuf1b+cqtjjd1onStPrtyny5daPdEJWinHBUJG-6hQ@mail.gmail.com \
    --to=enh@google.com \
    --cc=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    --cc=stsp@users.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).