1OPENAT2(2)                 Linux Programmer's Manual                OPENAT2(2)
2
3
4

NAME

6       openat2 - open and possibly create a file (extended)
7

SYNOPSIS

9       #include <sys/types.h>
10       #include <sys/stat.h>
11       #include <fcntl.h>
12       #include <openat2.h>
13
14       int openat2(int dirfd, const char *pathname,
15                   struct open_how *how, size_t size);
16
17       Note: There is no glibc wrapper for this system call; see NOTES.
18

DESCRIPTION

20       The  openat2()  system call is an extension of openat(2) and provides a
21       superset of its functionality.
22
23       The openat2() system call opens the file specified by pathname.  If the
24       specified  file does not exist, it may optionally (if O_CREAT is speci‐
25       fied in how.flags) be created.
26
27       As with openat(2), if pathname is  a  relative  pathname,  then  it  is
28       interpreted  relative to the directory referred to by the file descrip‐
29       tor dirfd (or the current working directory of the calling process,  if
30       dirfd is the special value AT_FDCWD).  If pathname is an absolute path‐
31       name,   then   dirfd   is   ignored   (unless   how.resolve    contains
32       RESOLVE_IN_ROOT, in which case pathname is resolved relative to dirfd).
33
34       Rather  than  taking  a  single flags argument, an extensible structure
35       (how) is passed to allow for future extensions.  The size argument must
36       be specified as sizeof(struct open_how).
37
38   The open_how structure
39       The how argument specifies how pathname should be opened, and acts as a
40       superset of the flags and mode arguments to openat(2).   This  argument
41       is a pointer to a structure of the following form:
42
43           struct open_how {
44               u64 flags;    /* O_* flags */
45               u64 mode;     /* Mode for O_{CREAT,TMPFILE} */
46               u64 resolve;  /* RESOLVE_* flags */
47               /* ... */
48           };
49
50       Any  future  extensions  to openat2() will be implemented as new fields
51       appended to the above structure, with a  zero  value  in  a  new  field
52       resulting in the kernel behaving as though that extension field was not
53       present.  Therefore, the caller must zero-fill this structure  on  ini‐
54       tialization.   (See  the  "Extensibility" section of the NOTES for more
55       detail on why this is necessary.)
56
57       The fields of the open_how structure are as follows:
58
59       flags  This field specifies the file creation and file status flags  to
60              use  when  opening  the  file.  All of the O_* flags defined for
61              openat(2) are valid openat2() flag values.
62
63              Whereas openat(2) ignores unknown bits in  its  flags  argument,
64              openat2()  returns  an error if unknown or conflicting flags are
65              specified in how.flags.
66
67       mode   This field specifies the mode for the new file,  with  identical
68              semantics to the mode argument of openat(2).
69
70              Whereas  openat(2)  ignores  bits  other than those in the range
71              07777 in its  mode  argument,  openat2()  returns  an  error  if
72              how.mode contains bits other than 07777.  Similarly, an error is
73              returned if openat2() is called with  a  non-zero  how.mode  and
74              how.flags does not contain O_CREAT or O_TMPFILE.
75
76       resolve
77              This  is  a  bit-mask  of flags that modify the way in which all
78              components of pathname  will  be  resolved.   (See  path_resolu‐
79              tion(7) for background information.)
80
81              The  primary  use  case for these flags is to allow trusted pro‐
82              grams to restrict how untrusted paths (or paths inside untrusted
83              directories) are resolved.  The full list of resolve flags is as
84              follows:
85
86              RESOLVE_BENEATH
87                     Do not permit the path resolution to succeed if any  com‐
88                     ponent  of  the  resolution  is  not  a descendant of the
89                     directory indicated by dirfd.  This causes absolute  sym‐
90                     bolic  links  (and  absolute  values  of  pathname) to be
91                     rejected.
92
93                     Currently, this flag also disables magic-link  resolution
94                     (see  below).   However,  this  may change in the future.
95                     Therefore, to ensure that magic links are  not  resolved,
96                     the  caller  should  explicitly  specify RESOLVE_NO_MAGI‐
97                     CLINKS.
98
99              RESOLVE_IN_ROOT
100                     Treat the directory referred to  by  dirfd  as  the  root
101                     directory  while  resolving  pathname.  Absolute symbolic
102                     links are interpreted relative to  dirfd.   If  a  prefix
103                     component  of  pathname equates to dirfd, then an immedi‐
104                     ately following ..  component likewise equates  to  dirfd
105                     (just  as  /..   is  traditionally  equivalent to /).  If
106                     pathname is an absolute path, it is also interpreted rel‐
107                     ative to dirfd.
108
109                     The  effect of this flag is as though the calling process
110                     had used  chroot(2)  to  (temporarily)  modify  its  root
111                     directory  (to the directory referred to by dirfd).  How‐
112                     ever, unlike chroot(2) (which changes the filesystem root
113                     permanently for a process), RESOLVE_IN_ROOT allows a pro‐
114                     gram to efficiently restrict path resolution  on  a  per-
115                     open basis.
116
117                     Currently, this flag also disables magic-link resolution.
118                     However, this may change in the  future.   Therefore,  to
119                     ensure  that  magic  links  are  not resolved, the caller
120                     should explicitly specify RESOLVE_NO_MAGICLINKS.
121
122              RESOLVE_NO_MAGICLINKS
123                     Disallow all magic-link resolution  during  path  resolu‐
124                     tion.
125
126                     Magic  links are symbolic link-like objects that are most
127                     notably    found    in    proc(5);    examples    include
128                     /proc/[pid]/exe  and  /proc/[pid]/fd/*.   (See symlink(7)
129                     for more details.)
130
131                     Unknowingly opening magic links can  be  risky  for  some
132                     applications.  Examples of such risks include the follow‐
133                     ing:
134
135                     · If the process opening  a  pathname  is  a  controlling
136                       process that currently has no controlling terminal (see
137                       credentials(7)),  then  opening  a  magic  link  inside
138                       /proc/[pid]/fd  that  happens  to  refer  to a terminal
139                       would cause the process to acquire a controlling termi‐
140                       nal.
141
142                     · In  a  containerized  environment,  a magic link inside
143                       /proc may refer to an object outside the container, and
144                       thus may provide a means to escape from the container.
145
146                     Because  of such risks, an application may prefer to dis‐
147                     able magic link  resolution  using  the  RESOLVE_NO_MAGI‐
148                     CLINKS flag.
149
150                     If the trailing component (i.e., basename) of pathname is
151                     a magic link, how.resolve contains RESOLVE_NO_MAGICLINKS,
152                     and  how.flags  contains both O_PATH and O_NOFOLLOW, then
153                     an O_PATH file descriptor referencing the magic link will
154                     be returned.
155
156              RESOLVE_NO_SYMLINKS
157                     Disallow resolution of symbolic links during path resolu‐
158                     tion.  This option implies RESOLVE_NO_MAGICLINKS.
159
160                     If the trailing component (i.e., basename) of pathname is
161                     a  symbolic  link,  how.resolve  contains RESOLVE_NO_SYM‐
162                     LINKS, and how.flags contains both O_PATH and O_NOFOLLOW,
163                     then  an  O_PATH file descriptor referencing the symbolic
164                     link will be returned.
165
166                     Note that the effect  of  the  RESOLVE_NO_SYMLINKS  flag,
167                     which  affects  the treatment of symbolic links in all of
168                     the components of pathname, differs from  the  effect  of
169                     the  O_NOFOLLOW  file creation flag (in how.flags), which
170                     affects the handling of symbolic links only in the  final
171                     component of pathname.
172
173                     Applications that employ the RESOLVE_NO_SYMLINKS flag are
174                     encouraged to make its use  configurable  (unless  it  is
175                     used  for a specific security purpose), as symbolic links
176                     are very widely used by  end-users.   Setting  this  flag
177                     indiscriminately—i.e.,   for  purposes  not  specifically
178                     related to security—for all uses of openat2() may  result
179                     in  spurious  errors  on  previously-functional  systems.
180                     This may occur if, for example, a system pathname that is
181                     used  by  an application is modified (e.g., in a new dis‐
182                     tribution release) so that  a  pathname  component  (now)
183                     contains a symbolic link.
184
185              RESOLVE_NO_XDEV
186                     Disallow traversal of mount points during path resolution
187                     (including all bind mounts).  Consequently, pathname must
188                     either  be on the same mount as the directory referred to
189                     by dirfd, or on the same mount  as  the  current  working
190                     directory if dirfd is specified as AT_FDCWD.
191
192                     Applications  that  employ  the  RESOLVE_NO_XDEV flag are
193                     encouraged to make its use  configurable  (unless  it  is
194                     used for a specific security purpose), as bind mounts are
195                     widely used by end-users.  Setting this flag  indiscrimi‐
196                     nately—i.e.,  for  purposes  not  specifically related to
197                     security—for all uses of openat2() may result in spurious
198                     errors  on previously-functional systems.  This may occur
199                     if, for example, a system pathname that  is  used  by  an
200                     application  is  modified  (e.g.,  in  a new distribution
201                     release) so that a pathname component  (now)  contains  a
202                     bind mount.
203
204              If   any   bits  other  than  those  listed  above  are  set  in
205              how.resolve, an error is returned.
206

RETURN VALUE

208       On success, a new  file  descriptor  is  returned.   On  error,  -1  is
209       returned, and errno is set appropriately.
210

ERRORS

212       The  set  of  errors  returned  by openat2() includes all of the errors
213       returned by openat(2), as well as the following additional errors:
214
215       E2BIG  An extension that this kernel does not support was specified  in
216              how.   (See the "Extensibility" section of NOTES for more detail
217              on how extensions are handled.)
218
219       EAGAIN how.resolve contains either RESOLVE_IN_ROOT or  RESOLVE_BENEATH,
220              and  the  kernel  could  not ensure that a ".." component didn't
221              escape (due to a race condition or potential attack).  The call‐
222              er may choose to retry the openat2() call.
223
224       EINVAL An unknown flag or invalid value was specified in how.
225
226       EINVAL mode  is  non-zero,  but  how.flags  does not contain O_CREAT or
227              O_TMPFILE.
228
229       EINVAL size was smaller than any known version of struct open_how.
230
231       ELOOP  how.resolve contains RESOLVE_NO_SYMLINKS, and one  of  the  path
232              components was a symbolic link (or magic link).
233
234       ELOOP  how.resolve  contains RESOLVE_NO_MAGICLINKS, and one of the path
235              components was a magic link.
236
237       EXDEV  how.resolve contains either RESOLVE_IN_ROOT or  RESOLVE_BENEATH,
238              and an escape from the root during path resolution was detected.
239
240       EXDEV  how.resolve  contains  RESOLVE_NO_XDEV,  and  a  path  component
241              crosses a mount point.
242

VERSIONS

244       openat2() first appeared in Linux 5.6.
245

CONFORMING TO

247       This system call is Linux-specific.
248
249       The  semantics  of  RESOLVE_BENEATH  were   modeled   after   FreeBSD's
250       O_BENEATH.
251

NOTES

253       Glibc  does  not  provide a wrapper for this system call; call it using
254       syscall(2).
255
256   Extensibility
257       In order to allow for  future  extensibility,  openat2()  requires  the
258       user-space  application  to  specify the size of the open_how structure
259       that it is passing.  By providing this information, it is possible  for
260       openat2()  to  provide both forwards- and backwards-compatibility, with
261       size acting as an implicit  version  number.   (Because  new  extension
262       fields  will  always  be  appended,  the  structure  size  will  always
263       increase.)  This extensibility design is very similar to  other  system
264       calls such as perf_setattr(2), perf_event_open(2), and clone3(2).
265
266       If  we let usize be the size of the structure as specified by the user-
267       space application, and ksize be the size of  the  structure  which  the
268       kernel supports, then there are three cases to consider:
269
270       · If  ksize equals usize, then there is no version mismatch and how can
271         be used verbatim.
272
273       · If ksize is larger than usize, then there are some  extension  fields
274         that  the kernel supports which the user-space application is unaware
275         of.  Because a zero value in any added extension  field  signifies  a
276         no-op,  the kernel treats all of the extension fields not provided by
277         the user-space application as  having  zero  values.   This  provides
278         backwards-compatibility.
279
280       · If  ksize is smaller than usize, then there are some extension fields
281         which the user-space application is aware of  but  which  the  kernel
282         does  not  support.   Because  any extension field must have its zero
283         values signify a no-op, the kernel can safely ignore the  unsupported
284         extension  fields if they are all-zero.  If any unsupported extension
285         fields are non-zero, then -1 is returned and errno is set  to  E2BIG.
286         This provides forwards-compatibility.
287
288       Because  the  definition  of  struct  open_how may change in the future
289       (with new fields being added when system headers  are  updated),  user-
290       space  applications  should  zero-fill  struct  open_how to ensure that
291       recompiling the program with new headers will not  result  in  spurious
292       errors  at  runtime.   The simplest way is to use a designated initial‐
293       izer:
294
295           struct open_how how = { .flags = O_RDWR,
296                                   .resolve = RESOLVE_IN_ROOT };
297
298       or explicitly using memset(3) or similar:
299
300           struct open_how how;
301           memset(&how, 0, sizeof(how));
302           how.flags = O_RDWR;
303           how.resolve = RESOLVE_IN_ROOT;
304
305       A user-space application that wishes to determine which extensions  the
306       running kernel supports can do so by conducting a binary search on size
307       with a structure which has every byte  nonzero  (to  find  the  largest
308       value which doesn't produce an error of E2BIG).
309

SEE ALSO

311       openat(2), path_resolution(7), symlink(7)
312

COLOPHON

314       This  page  is  part of release 5.07 of the Linux man-pages project.  A
315       description of the project, information about reporting bugs,  and  the
316       latest     version     of     this    page,    can    be    found    at
317       https://www.kernel.org/doc/man-pages/.
318
319
320
321Linux                             2020-04-11                        OPENAT2(2)
Impressum