]> git.saurik.com Git - apple/xnu.git/blob - libsyscall/wrappers/open-base.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / libsyscall / wrappers / open-base.c
1 /*
2 * Copyright (c) 2020 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <fcntl.h>
25 #include <stdarg.h>
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <TargetConditionals.h>
29
30 #if !defined(__i386__)
31
32 #if TARGET_OS_OSX
33 #include <stdbool.h>
34
35 /*
36 * On macOS we have support for shimming calls to open the SystemVersion plist.
37 * This support is enabled for specific (generally older) binaries from
38 * libSystem_initializer()/__libkernel_init_late() by populating these function pointers
39 * with the corresponding functions built into libsyscall_dynamic (see open-compat-shim.c).
40 */
41 extern bool (*system_version_compat_check_path_suffix)(const char *orig_path);
42 extern int (*system_version_compat_open_shim)(int opened_fd, int openat_fd, const char *orig_path, int oflag, mode_t mode,
43 int (*close_syscall)(int), int (*open_syscall)(const char *, int, mode_t),
44 int (*openat_syscall)(int, const char *, int, mode_t),
45 int (*fcntl_syscall)(int, int, long));
46 #endif /* TARGET_OS_OSX */
47
48 #ifdef VARIANT_CANCELABLE
49 int __open(const char *path, int oflag, mode_t mode);
50 int __openat(int fd, const char *path, int oflag, mode_t mode);
51
52 #define OPEN_SYSCALL __open
53 #define OPENAT_SYSCALL __openat
54
55 #if TARGET_OS_OSX
56 int __fcntl(int fd, int cmd, long arg);
57 int close(int fd);
58
59 #define FCNTL_SYSCALL __fcntl
60 #define CLOSE_SYSCALL close
61 #endif /* TARGET_OS_OSX */
62
63 #else /* VARIANT_CANCELABLE */
64 int __open_nocancel(const char *path, int oflag, mode_t mode);
65 int __openat_nocancel(int fd, const char *path, int oflag, mode_t mode);
66
67 #define OPEN_SYSCALL __open_nocancel
68 #define OPENAT_SYSCALL __openat_nocancel
69
70 #if TARGET_OS_OSX
71 int __fcntl_nocancel(int fd, int cmd, long arg);
72 int __close_nocancel(int fd);
73
74 #define FCNTL_SYSCALL __fcntl_nocancel
75 #define CLOSE_SYSCALL __close_nocancel
76 #endif /* TARGET_OS_OSX */
77 #endif /* VARIANT_CANCELABLE */
78
79 #ifdef VARIANT_CANCELABLE
80 int
81 open(const char *path, int oflag, ...)
82 #else /* VARIANT_CANCELABLE */
83 int
84 open$NOCANCEL(const char *path, int oflag, ...)
85 #endif
86 {
87 int opened_fd = 0;
88 mode_t mode = 0;
89
90 if (oflag & O_CREAT) {
91 va_list ap;
92 va_start(ap, oflag);
93 /* compiler warns to pass int (not mode_t) to va_arg */
94 mode = va_arg(ap, int);
95 va_end(ap);
96 }
97
98 opened_fd = OPEN_SYSCALL(path, oflag, mode);
99 #if !TARGET_OS_OSX
100 return opened_fd;
101 #else /* TARGET_OS_OSX */
102 if (opened_fd < 0) {
103 return opened_fd;
104 }
105
106 /* check to see if system_version_compat is enabled for this process */
107 if (system_version_compat_check_path_suffix == NULL) {
108 return opened_fd;
109 }
110
111 /* check to see if the suffix of the path we opened matches one we are shimming */
112 if (!system_version_compat_check_path_suffix(path)) {
113 return opened_fd;
114 }
115
116 /* at this point we call into the version compat open shim and return values from there */
117 return system_version_compat_open_shim(opened_fd, -1, path, oflag, mode, CLOSE_SYSCALL, OPEN_SYSCALL,
118 NULL, FCNTL_SYSCALL);
119 #endif /* TARGET_OS_OSX */
120 }
121
122 #ifdef VARIANT_CANCELABLE
123 int
124 openat(int fd, const char *path, int oflag, ...)
125 #else /* VARIANT_CANCELABLE */
126 int
127 openat$NOCANCEL(int fd, const char *path, int oflag, ...)
128 #endif
129 {
130 int opened_fd = 0;
131 mode_t mode = 0;
132
133 if (oflag & O_CREAT) {
134 va_list ap;
135 va_start(ap, oflag);
136 // compiler warns to pass int (not mode_t) to va_arg
137 mode = va_arg(ap, int);
138 va_end(ap);
139 }
140
141 opened_fd = OPENAT_SYSCALL(fd, path, oflag, mode);
142 #if !TARGET_OS_OSX
143 return opened_fd;
144 #else
145 if (opened_fd < 0) {
146 return opened_fd;
147 }
148
149 /* check to see if system_version_compat is enabled for this process */
150 if (system_version_compat_check_path_suffix == NULL) {
151 return opened_fd;
152 }
153
154 /* check to see if the suffix of the path we opened matches one we are shimming */
155 if (!system_version_compat_check_path_suffix(path)) {
156 return opened_fd;
157 }
158
159 /* at this point we call into the version compat open shim and return values from there */
160 return system_version_compat_open_shim(opened_fd, fd, path, oflag, mode, CLOSE_SYSCALL, NULL,
161 OPENAT_SYSCALL, FCNTL_SYSCALL);
162 #endif /* !TARGET_OS_OSX */
163 }
164 #endif /* !defined(__i386__) */