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



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.

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:01 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 [this message]
2024-04-25 14:10         ` enh
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=50263380-712c-4348-a249-3ca6edd2d833@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=enh@google.com \
    --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).