dwww Home | Manual pages | Find package

openat2(2)                    System Calls Manual                   openat2(2)

NAME
       openat2 - open and possibly create a file (extended)

LIBRARY
       Standard C library (libc, -lc)

SYNOPSIS
       #include <fcntl.h>          /* Definition of O_* and S_* constants */
       #include <linux/openat2.h>  /* Definition of RESOLVE_* constants */
       #include <sys/syscall.h>    /* Definition of SYS_* constants */
       #include <unistd.h>

       long syscall(SYS_openat2, int dirfd, const char *pathname,
                    struct open_how *how, size_t size);

       Note: glibc provides no wrapper for openat2(), necessitating the use of
       syscall(2).

DESCRIPTION
       The  openat2()  system call is an extension of openat(2) and provides a
       superset of its functionality.

       The openat2() system call opens the file specified by pathname.  If the
       specified file does not exist, it may optionally (if O_CREAT is  speci-
       fied in how.flags) be created.

       As  with  openat(2), if pathname is a relative pathname, then it is in-
       terpreted relative to the directory referred to by the file  descriptor
       dirfd  (or  the  current  working  directory of the calling process, if
       dirfd is the special value AT_FDCWD).  If pathname is an absolute path-
       name,  then  dirfd  is  ignored  (unless   how.resolve   contains   RE-
       SOLVE_IN_ROOT, in which case pathname is resolved relative to dirfd).

       Rather  than  taking  a  single flags argument, an extensible structure
       (how) is passed to allow for future extensions.  The size argument must
       be specified as sizeof(struct open_how).

   The open_how structure
       The how argument specifies how pathname should be opened, and acts as a
       superset of the flags and mode arguments to openat(2).   This  argument
       is a pointer to an open_how structure, described in open_how(2type).

       Any  future  extensions  to openat2() will be implemented as new fields
       appended to the open_how structure, with a zero value in  a  new  field
       resulting in the kernel behaving as though that extension field was not
       present.   Therefore,  the caller must zero-fill this structure on ini-
       tialization.  (See the "Extensibility" section of the  NOTES  for  more
       detail on why this is necessary.)

       The fields of the open_how structure are as follows:

       flags  This  field specifies the file creation and file status flags to
              use when opening the file.  All of the  O_*  flags  defined  for
              openat(2) are valid openat2() flag values.

              Whereas  openat(2)  ignores  unknown bits in its flags argument,
              openat2() returns an error if unknown or conflicting  flags  are
              specified in how.flags.

       mode   This  field  specifies the mode for the new file, with identical
              semantics to the mode argument of openat(2).

              Whereas openat(2) ignores bits other than  those  in  the  range
              07777  in  its  mode  argument,  openat2()  returns  an error if
              how.mode contains bits other than 07777.  Similarly, an error is
              returned if openat2() is called  with  a  nonzero  how.mode  and
              how.flags does not contain O_CREAT or O_TMPFILE.

       resolve
              This  is  a  bit-mask  of flags that modify the way in which all
              components of pathname  will  be  resolved.   (See  path_resolu-
              tion(7) for background information.)

              The  primary  use  case for these flags is to allow trusted pro-
              grams to restrict how untrusted paths (or paths inside untrusted
              directories) are resolved.  The full list of resolve flags is as
              follows:

              RESOLVE_BENEATH
                     Do not permit the path resolution to succeed if any  com-
                     ponent  of  the resolution is not a descendant of the di-
                     rectory indicated by dirfd.  This  causes  absolute  sym-
                     bolic  links  (and absolute values of pathname) to be re-
                     jected.

                     Currently, this flag also disables magic-link  resolution
                     (see  below).   However,  this  may change in the future.
                     Therefore, to ensure that magic links are  not  resolved,
                     the  caller  should  explicitly  specify RESOLVE_NO_MAGI-
                     CLINKS.

              RESOLVE_IN_ROOT
                     Treat the directory referred to by dirfd as the root  di-
                     rectory  while  resolving  pathname.   Absolute  symbolic
                     links are interpreted relative to  dirfd.   If  a  prefix
                     component  of  pathname equates to dirfd, then an immedi-
                     ately following .. component likewise  equates  to  dirfd
                     (just as /.. is traditionally equivalent to /).  If path-
                     name is an absolute path, it is also interpreted relative
                     to dirfd.

                     The  effect of this flag is as though the calling process
                     had used chroot(2) to (temporarily) modify its  root  di-
                     rectory  (to  the  directory referred to by dirfd).  How-
                     ever, unlike chroot(2) (which changes the filesystem root
                     permanently for a process), RESOLVE_IN_ROOT allows a pro-
                     gram to efficiently restrict path resolution  on  a  per-
                     open basis.

                     Currently, this flag also disables magic-link resolution.
                     However,  this  may  change in the future.  Therefore, to
                     ensure that magic links  are  not  resolved,  the  caller
                     should explicitly specify RESOLVE_NO_MAGICLINKS.

              RESOLVE_NO_MAGICLINKS
                     Disallow  all  magic-link  resolution during path resolu-
                     tion.

                     Magic links are symbolic link-like objects that are  most
                     notably  found in proc(5); examples include /proc/pid/exe
                     and /proc/pid/fd/*.  (See symlink(7) for more details.)

                     Unknowingly opening magic links can be risky for some ap-
                     plications.  Examples of such risks include  the  follow-
                     ing:

                     •  If  the  process  opening  a pathname is a controlling
                        process that currently  has  no  controlling  terminal
                        (see credentials(7)), then opening a magic link inside
                        /proc/pid/fd that happens to refer to a terminal would
                        cause the process to acquire a controlling terminal.

                     •  In  a  containerized  environment, a magic link inside
                        /proc may refer to an object  outside  the  container,
                        and  thus  may provide a means to escape from the con-
                        tainer.

                     Because of such risks, an application may prefer to  dis-
                     able  magic  link  resolution  using the RESOLVE_NO_MAGI-
                     CLINKS flag.

                     If the trailing component (i.e., basename) of pathname is
                     a magic link, how.resolve contains RESOLVE_NO_MAGICLINKS,
                     and how.flags contains both O_PATH and  O_NOFOLLOW,  then
                     an O_PATH file descriptor referencing the magic link will
                     be returned.

              RESOLVE_NO_SYMLINKS
                     Disallow resolution of symbolic links during path resolu-
                     tion.  This option implies RESOLVE_NO_MAGICLINKS.

                     If the trailing component (i.e., basename) of pathname is
                     a  symbolic  link,  how.resolve  contains RESOLVE_NO_SYM-
                     LINKS, and how.flags contains both O_PATH and O_NOFOLLOW,
                     then an O_PATH file descriptor referencing  the  symbolic
                     link will be returned.

                     Note  that  the  effect  of the RESOLVE_NO_SYMLINKS flag,
                     which affects the treatment of symbolic links in  all  of
                     the  components  of  pathname, differs from the effect of
                     the O_NOFOLLOW file creation flag (in  how.flags),  which
                     affects  the handling of symbolic links only in the final
                     component of pathname.

                     Applications that employ the RESOLVE_NO_SYMLINKS flag are
                     encouraged to make its use  configurable  (unless  it  is
                     used  for a specific security purpose), as symbolic links
                     are very widely used by end-users.  Setting this flag in-
                     discriminately—i.e., for purposes  not  specifically  re-
                     lated to security—for all uses of openat2() may result in
                     spurious  errors  on previously functional systems.  This
                     may occur if, for example, a system pathname that is used
                     by an application is modified (e.g., in a  new  distribu-
                     tion release) so that a pathname component (now) contains
                     a symbolic link.

              RESOLVE_NO_XDEV
                     Disallow traversal of mount points during path resolution
                     (including all bind mounts).  Consequently, pathname must
                     either  be on the same mount as the directory referred to
                     by dirfd, or on the same mount as the current working di-
                     rectory if dirfd is specified as AT_FDCWD.

                     Applications that employ the RESOLVE_NO_XDEV flag are en-
                     couraged to make its use configurable (unless it is  used
                     for  a  specific  security  purpose),  as bind mounts are
                     widely used by end-users.  Setting this flag  indiscrimi-
                     nately—i.e., for purposes not specifically related to se-
                     curity—for  all  uses of openat2() may result in spurious
                     errors on previously functional systems.  This may  occur
                     if, for example, a system pathname that is used by an ap-
                     plication  is  modified  (e.g., in a new distribution re-
                     lease) so that a pathname component (now) contains a bind
                     mount.

              RESOLVE_CACHED
                     Make the open operation fail unless all  path  components
                     are already present in the kernel's lookup cache.  If any
                     kind  of  revalidation  or  I/O  is needed to satisfy the
                     lookup, openat2() fails with the error EAGAIN.   This  is
                     useful  in  providing  a  fast-path open that can be per-
                     formed without resorting  to  thread  offload,  or  other
                     mechanisms  that  an  application  might  use  to offload
                     slower operations.

              If any bits other than those listed above  are  set  in  how.re-
              solve, an error is returned.

RETURN VALUE
       On  success,  a  new  file descriptor is returned.  On error, -1 is re-
       turned, and errno is set to indicate the error.

ERRORS
       The set of errors returned by openat2() includes all of the errors  re-
       turned by openat(2), as well as the following additional errors:

       E2BIG  An  extension that this kernel does not support was specified in
              how.  (See the "Extensibility" section of NOTES for more  detail
              on how extensions are handled.)

       EAGAIN how.resolve  contains either RESOLVE_IN_ROOT or RESOLVE_BENEATH,
              and the kernel could not ensure that a ".." component didn't es-
              cape (due to a race condition or potential attack).  The  caller
              may choose to retry the openat2() call.

       EAGAIN RESOLVE_CACHED  was  set,  and the open operation cannot be per-
              formed using only cached information.  The caller  should  retry
              without RESOLVE_CACHED set in how.resolve.

       EINVAL An unknown flag or invalid value was specified in how.

       EINVAL mode  is  nonzero,  but  how.flags  does  not contain O_CREAT or
              O_TMPFILE.

       EINVAL size was smaller than any known version of struct open_how.

       ELOOP  how.resolve contains RESOLVE_NO_SYMLINKS, and one  of  the  path
              components was a symbolic link (or magic link).

       ELOOP  how.resolve  contains RESOLVE_NO_MAGICLINKS, and one of the path
              components was a magic link.

       EXDEV  how.resolve contains either RESOLVE_IN_ROOT or  RESOLVE_BENEATH,
              and an escape from the root during path resolution was detected.

       EXDEV  how.resolve  contains  RESOLVE_NO_XDEV,  and  a  path  component
              crosses a mount point.

STANDARDS
       Linux.

HISTORY
       Linux 5.6.

       The semantics of RESOLVE_BENEATH were  modeled  after  FreeBSD's  O_BE-
       NEATH.

NOTES
   Extensibility
       In  order  to  allow  for  future extensibility, openat2() requires the
       user-space application to specify the size of  the  open_how  structure
       that  it is passing.  By providing this information, it is possible for
       openat2() to provide both forwards- and  backwards-compatibility,  with
       size  acting  as  an  implicit  version number.  (Because new extension
       fields will always be appended, the  structure  size  will  always  in-
       crease.)   This  extensibility  design  is very similar to other system
       calls such as sched_setattr(2), perf_event_open(2), and clone3(2).

       If we let usize be the size of the structure as specified by the  user-
       space  application,  and  ksize  be the size of the structure which the
       kernel supports, then there are three cases to consider:

       •  If ksize equals usize, then there is no version mismatch and how can
          be used verbatim.

       •  If ksize is larger than usize, then there are some extension  fields
          that the kernel supports which the user-space application is unaware
          of.   Because  a zero value in any added extension field signifies a
          no-op, the kernel treats all of the extension fields not provided by
          the user-space application as having  zero  values.   This  provides
          backwards-compatibility.

       •  If ksize is smaller than usize, then there are some extension fields
          which  the  user-space  application is aware of but which the kernel
          does not support.  Because any extension field must  have  its  zero
          values signify a no-op, the kernel can safely ignore the unsupported
          extension fields if they are all-zero.  If any unsupported extension
          fields  are  nonzero, then -1 is returned and errno is set to E2BIG.
          This provides forwards-compatibility.

       Because the definition of struct open_how  may  change  in  the  future
       (with  new  fields  being added when system headers are updated), user-
       space applications should zero-fill struct open_how to ensure that  re-
       compiling  the program with new headers will not result in spurious er-
       rors at run time.  The simplest way is to use a designated initializer:

           struct open_how how = { .flags = O_RDWR,
                                   .resolve = RESOLVE_IN_ROOT };

       or explicitly using memset(3) or similar:

           struct open_how how;
           memset(&how, 0, sizeof(how));
           how.flags = O_RDWR;
           how.resolve = RESOLVE_IN_ROOT;

       A user-space application that wishes to determine which extensions  the
       running kernel supports can do so by conducting a binary search on size
       with  a  structure  which  has  every byte nonzero (to find the largest
       value which doesn't produce an error of E2BIG).

SEE ALSO
       openat(2), open_how(2type), path_resolution(7), symlink(7)

Linux man-pages 6.7               2024-02-25                        openat2(2)

Generated by dwww version 1.16 on Tue Dec 16 06:24:10 CET 2025.