]>
Commit | Line | Data |
---|---|---|
f427ee49 A |
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__) */ |