master
  1/* Checking macros for fcntl functions.
  2   Copyright (C) 2007-2025 Free Software Foundation, Inc.
  3   This file is part of the GNU C Library.
  4
  5   The GNU C Library is free software; you can redistribute it and/or
  6   modify it under the terms of the GNU Lesser General Public
  7   License as published by the Free Software Foundation; either
  8   version 2.1 of the License, or (at your option) any later version.
  9
 10   The GNU C Library is distributed in the hope that it will be useful,
 11   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13   Lesser General Public License for more details.
 14
 15   You should have received a copy of the GNU Lesser General Public
 16   License along with the GNU C Library; if not, see
 17   <https://www.gnu.org/licenses/>.  */
 18
 19#ifndef	_FCNTL_H
 20# error "Never include <bits/fcntl2.h> directly; use <fcntl.h> instead."
 21#endif
 22
 23/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
 24   appropriate third/fourth parameter.  */
 25#ifndef __USE_FILE_OFFSET64
 26extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
 27extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
 28		       open) __nonnull ((1));
 29#else
 30extern int __REDIRECT (__open_2, (const char *__path, int __oflag),
 31		       __open64_2) __nonnull ((1));
 32extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
 33		       open64) __nonnull ((1));
 34#endif
 35
 36#ifdef __va_arg_pack_len
 37__errordecl (__open_too_many_args,
 38	     "open can be called either with 2 or 3 arguments, not more");
 39__errordecl (__open_missing_mode,
 40	     "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 41
 42__fortify_function int
 43open (const char *__path, int __oflag, ...)
 44{
 45  if (__va_arg_pack_len () > 1)
 46    __open_too_many_args ();
 47
 48  if (__builtin_constant_p (__oflag))
 49    {
 50      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 51	{
 52	  __open_missing_mode ();
 53	  return __open_2 (__path, __oflag);
 54	}
 55      return __open_alias (__path, __oflag, __va_arg_pack ());
 56    }
 57
 58  if (__va_arg_pack_len () < 1)
 59    return __open_2 (__path, __oflag);
 60
 61  return __open_alias (__path, __oflag, __va_arg_pack ());
 62}
 63#elif __fortify_use_clang
 64__fortify_function __attribute_overloadable__ int
 65open (__fortify_clang_overload_arg (const char *, ,__path), int __oflag)
 66     __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
 67			    "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments")
 68{
 69  return __open_2 (__path, __oflag);
 70}
 71
 72__fortify_function __attribute_overloadable__ int
 73open (__fortify_clang_overload_arg (const char *, ,__path), int __oflag,
 74      mode_t __mode)
 75{
 76  return __open_alias (__path, __oflag, __mode);
 77}
 78#endif
 79
 80
 81#ifdef __USE_LARGEFILE64
 82extern int __open64_2 (const char *__path, int __oflag) __nonnull ((1));
 83extern int __REDIRECT (__open64_alias, (const char *__path, int __oflag,
 84					...), open64) __nonnull ((1));
 85# ifdef __va_arg_pack_len
 86__errordecl (__open64_too_many_args,
 87	     "open64 can be called either with 2 or 3 arguments, not more");
 88__errordecl (__open64_missing_mode,
 89	     "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 90
 91__fortify_function int
 92open64 (const char *__path, int __oflag, ...)
 93{
 94  if (__va_arg_pack_len () > 1)
 95    __open64_too_many_args ();
 96
 97  if (__builtin_constant_p (__oflag))
 98    {
 99      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
100	{
101	  __open64_missing_mode ();
102	  return __open64_2 (__path, __oflag);
103	}
104      return __open64_alias (__path, __oflag, __va_arg_pack ());
105    }
106
107  if (__va_arg_pack_len () < 1)
108    return __open64_2 (__path, __oflag);
109
110  return __open64_alias (__path, __oflag, __va_arg_pack ());
111}
112# elif __fortify_use_clang
113__fortify_function_error_function __attribute_overloadable__ int
114open64 (const char *__path, int __oflag, mode_t __mode, ...)
115     __fortify_clang_unavailable ("open64 can be called either with 2 or 3 arguments, not more");
116
117__fortify_function __attribute_overloadable__ int
118open64 (__fortify_clang_overload_arg (const char *, ,__path), int __oflag)
119     __fortify_clang_prefer_this_overload
120     __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
121			    "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments")
122{
123  return __open64_2 (__path, __oflag);
124}
125
126__fortify_function __attribute_overloadable__ int
127open64 (__fortify_clang_overload_arg (const char *, ,__path), int __oflag,
128	mode_t __mode)
129{
130  return __open64_alias (__path, __oflag, __mode);
131}
132# endif
133#endif
134
135
136#ifdef __USE_ATFILE
137# ifndef __USE_FILE_OFFSET64
138extern int __openat_2 (int __fd, const char *__path, int __oflag)
139     __nonnull ((2));
140extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
141					int __oflag, ...), openat)
142     __nonnull ((2));
143# else
144extern int __REDIRECT (__openat_2, (int __fd, const char *__path,
145				    int __oflag), __openat64_2)
146     __nonnull ((2));
147extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
148					int __oflag, ...), openat64)
149     __nonnull ((2));
150# endif
151
152# ifdef __va_arg_pack_len
153__errordecl (__openat_too_many_args,
154	     "openat can be called either with 3 or 4 arguments, not more");
155__errordecl (__openat_missing_mode,
156	     "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
157
158__fortify_function int
159openat (int __fd, const char *__path, int __oflag, ...)
160{
161  if (__va_arg_pack_len () > 1)
162    __openat_too_many_args ();
163
164  if (__builtin_constant_p (__oflag))
165    {
166      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
167	{
168	  __openat_missing_mode ();
169	  return __openat_2 (__fd, __path, __oflag);
170	}
171      return __openat_alias (__fd, __path, __oflag, __va_arg_pack ());
172    }
173
174  if (__va_arg_pack_len () < 1)
175    return __openat_2 (__fd, __path, __oflag);
176
177  return __openat_alias (__fd, __path, __oflag, __va_arg_pack ());
178}
179# elif __fortify_use_clang
180__fortify_function_error_function __attribute_overloadable__ int
181openat (int __fd, const char *__path, int __oflag, mode_t __mode, ...)
182     __fortify_clang_unavailable ("openat can be called either with 3 or 4 arguments, not more");
183
184__fortify_function __attribute_overloadable__ int
185openat (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
186	int __oflag)
187     __fortify_clang_prefer_this_overload
188     __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
189			    "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments")
190{
191  return __openat_2 (__fd, __path, __oflag);
192}
193
194__fortify_function __attribute_overloadable__ int
195openat (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
196	int __oflag, mode_t __mode)
197{
198  return __openat_alias (__fd, __path, __oflag, __mode);
199}
200# endif
201
202
203# ifdef __USE_LARGEFILE64
204extern int __openat64_2 (int __fd, const char *__path, int __oflag)
205     __nonnull ((2));
206extern int __REDIRECT (__openat64_alias, (int __fd, const char *__path,
207					  int __oflag, ...), openat64)
208     __nonnull ((2));
209__errordecl (__openat64_too_many_args,
210	     "openat64 can be called either with 3 or 4 arguments, not more");
211__errordecl (__openat64_missing_mode,
212	     "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
213
214#  ifdef __va_arg_pack_len
215__fortify_function int
216openat64 (int __fd, const char *__path, int __oflag, ...)
217{
218  if (__va_arg_pack_len () > 1)
219    __openat64_too_many_args ();
220
221  if (__builtin_constant_p (__oflag))
222    {
223      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
224	{
225	  __openat64_missing_mode ();
226	  return __openat64_2 (__fd, __path, __oflag);
227	}
228      return __openat64_alias (__fd, __path, __oflag, __va_arg_pack ());
229    }
230
231  if (__va_arg_pack_len () < 1)
232    return __openat64_2 (__fd, __path, __oflag);
233
234  return __openat64_alias (__fd, __path, __oflag, __va_arg_pack ());
235}
236# elif __fortify_use_clang
237__fortify_function_error_function __attribute_overloadable__ int
238openat64 (int __fd, const char *__path, int __oflag, mode_t __mode, ...)
239     __fortify_clang_unavailable ("openat64 can be called either with 3 or 4 arguments, not more");
240
241__fortify_function __attribute_overloadable__ int
242openat64 (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
243	  int __oflag)
244     __fortify_clang_prefer_this_overload
245     __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
246			    "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments")
247{
248  return __openat64_2 (__fd, __path, __oflag);
249}
250
251__fortify_function __attribute_overloadable__ int
252openat64 (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
253	  int __oflag, mode_t __mode)
254{
255  return __openat64_alias (__fd, __path, __oflag, __mode);
256}
257#  endif
258# endif
259#endif