1openat2(2)                    System Calls Manual                   openat2(2)
2
3
4

NAME

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

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #include <fcntl.h>          /* Definition of O_* and S_* constants */
13       #include <linux/openat2.h>  /* Definition of RESOLVE_* constants */
14       #include <sys/syscall.h>    /* Definition of SYS_* constants */
15       #include <unistd.h>
16
17       long syscall(SYS_openat2, int dirfd, const char *pathname,
18                    struct open_how *how, size_t size);
19
20       Note: glibc provides no wrapper for openat2(), necessitating the use of
21       syscall(2).
22

DESCRIPTION

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

RETURN VALUE

214       On  success,  a  new  file descriptor is returned.  On error, -1 is re‐
215       turned, and errno is set to indicate the error.
216

ERRORS

218       The set of errors returned by openat2() includes all of the errors  re‐
219       turned by openat(2), as well as the following additional errors:
220
221       E2BIG  An  extension that this kernel does not support was specified in
222              how.  (See the "Extensibility" section of NOTES for more  detail
223              on how extensions are handled.)
224
225       EAGAIN how.resolve  contains either RESOLVE_IN_ROOT or RESOLVE_BENEATH,
226              and the kernel could not ensure that a ".." component didn't es‐
227              cape  (due to a race condition or potential attack).  The caller
228              may choose to retry the openat2() call.
229
230       EAGAIN RESOLVE_CACHED was set, and the open operation  cannot  be  per‐
231              formed  using  only cached information.  The caller should retry
232              without RESOLVE_CACHED set in how.resolve .
233
234       EINVAL An unknown flag or invalid value was specified in how.
235
236       EINVAL mode is nonzero, but  how.flags  does  not  contain  O_CREAT  or
237              O_TMPFILE.
238
239       EINVAL size was smaller than any known version of struct open_how.
240
241       ELOOP  how.resolve  contains  RESOLVE_NO_SYMLINKS,  and one of the path
242              components was a symbolic link (or magic link).
243
244       ELOOP  how.resolve contains RESOLVE_NO_MAGICLINKS, and one of the  path
245              components was a magic link.
246
247       EXDEV  how.resolve  contains either RESOLVE_IN_ROOT or RESOLVE_BENEATH,
248              and an escape from the root during path resolution was detected.
249
250       EXDEV  how.resolve  contains  RESOLVE_NO_XDEV,  and  a  path  component
251              crosses a mount point.
252

STANDARDS

254       Linux.
255

HISTORY

257       Linux 5.6.
258
259       The  semantics  of  RESOLVE_BENEATH  were modeled after FreeBSD's O_BE‐
260       NEATH.
261

NOTES

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

SEE ALSO

317       openat(2), open_how(2type), path_resolution(7), symlink(7)
318
319
320
321Linux man-pages 6.04              2023-03-30                        openat2(2)
Impressum