xref: /xnu-8020.140.41/iokit/IOKit/IOUserServer.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1 /*
2  * Copyright (c) 2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 
30 #ifndef _IOUSERSERVER_H
31 #define _IOUSERSERVER_H
32 
33 #include <IOKit/IORPC.h>
34 
35 #define kIOUserClassKey        "IOUserClass"
36 #define kIOUserServerClassKey  "IOUserServer"
37 #define kIOUserServerNameKey   "IOUserServerName"
38 #define kIOUserServerTagKey    "IOUserServerTag"
39 // the expected cdhash value of the userspace driver executable
40 #define kIOUserServerCDHashKey "IOUserServerCDHash"
41 
42 #if DRIVERKIT_PRIVATE
43 
44 enum{
45 	kIOKitUserServerClientType  = 0x99000003,
46 };
47 
48 enum{
49 	kIOUserServerMethodRegisterClass = 0x0001000,
50 	kIOUserServerMethodStart         = 0x0001001,
51 	kIOUserServerMethodRegister      = 0x0001002,
52 };
53 
54 
55 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
56 
57 #define OSObject_Instantiate_ID       0x0000000100000001ULL
58 
59 enum {
60 	kOSObjectRPCRemote = 0x00000001,
61 	kOSObjectRPCKernel = 0x00000002,
62 };
63 
64 struct OSObject_Instantiate_Msg_Content {
65 	IORPCMessage __hdr;
66 	OSObjectRef  __object;
67 };
68 
69 struct OSObject_Instantiate_Rpl_Content {
70 	IORPCMessage  __hdr;
71 	kern_return_t __result;
72 	uint32_t      __pad;
73 	uint64_t      flags;
74 	char          classname[128];
75 	uint64_t      methods[0];
76 };
77 
78 #pragma pack(4)
79 struct OSObject_Instantiate_Msg {
80 	IORPCMessageMach mach;
81 	mach_msg_port_descriptor_t __object__descriptor;
82 	OSObject_Instantiate_Msg_Content content;
83 };
84 struct OSObject_Instantiate_Rpl {
85 	IORPCMessageMach mach;
86 	OSObject_Instantiate_Rpl_Content content;
87 };
88 #pragma pack()
89 
90 typedef uint64_t IOTrapMessageBuffer[256];
91 
92 #endif /* DRIVERKIT_PRIVATE */
93 
94 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
95 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
96 
97 #ifdef XNU_KERNEL_PRIVATE
98 
99 #include <IOKit/IOService.h>
100 #include <IOKit/IOUserClient.h>
101 #include <DriverKit/IOUserServer.h>
102 #include <libkern/c++/OSPtr.h>
103 #include <libkern/c++/OSKext.h>
104 
105 class IOUserServer;
106 class OSUserMetaClass;
107 class OSObject;
108 class IODispatchQueue;
109 class IODispatchSource;
110 class IOInterruptDispatchSource;
111 class IOTimerDispatchSource;
112 class IOUserServerCheckInToken;
113 struct IOPStrings;
114 
115 struct OSObjectUserVars {
116 	IOUserServer     * userServer;
117 	IODispatchQueue ** queueArray;
118 	OSUserMetaClass  * userMeta;
119 	OSArray          * openProviders;
120 	IOService        * controllingDriver;
121 	unsigned long      willPowerState;
122 	bool               willTerminate;
123 	bool               didTerminate;
124 	bool               serverDied;
125 	bool               started;
126 	bool               stopped;
127 	bool               userServerPM;
128 	bool               willPower;
129 	bool               powerState;
130 	uint32_t           powerOverride;
131 	IOLock           * uvarsLock;
132 };
133 
134 extern IOLock *        gIOUserServerLock;
135 
136 typedef struct ipc_kmsg * ipc_kmsg_t;
137 
138 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
139 
140 namespace IOServicePH
141 {
142 void serverAdd(IOUserServer * server);
143 void serverRemove(IOUserServer * server);
144 void serverAck(IOUserServer * server);
145 bool serverSlept(void);
146 void systemHalt(int howto);
147 };
148 
149 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
150 
151 class IOUserServer : public IOUserClient
152 {
153 	OSDeclareDefaultStructorsWithDispatch(IOUserServer);
154 
155 	IOLock       *        fLock;
156 	IOSimpleLock *        fInterruptLock;
157 	task_t                fOwningTask;
158 	OSDictionary  *       fEntitlements;
159 	OSDictionary  *       fClasses;
160 	IODispatchQueue     * fRootQueue;
161 	OSArray             * fServices;
162 
163 	uint8_t               fRootNotifier;
164 	uint8_t               fSystemPowerAck;
165 	uint8_t               fSystemOff;
166 	IOUserServerCheckInToken * fCheckInToken;
167 public:
168 	kern_allocation_name_t fAllocationName;
169 
170 public:
171 
172 	/*
173 	 * Launch a dext with the specified bundle ID, server name, and server tag. If reuseIfExists is true, this will attempt to find an existing IOUserServer instance or
174 	 * a pending dext launch with the same server name.
175 	 *
176 	 * Returns a IOUserServer instance if one was found, or a token to track the pending dext launch. If both are NULL, then launching the dext failed.
177 	 */
178 	static  IOUserServer * launchUserServer(OSString * bundleID, const OSSymbol * serverName, OSNumber * serverTag, bool reuseIfExists, IOUserServerCheckInToken ** token);
179 	static  IOUserClient * withTask(task_t owningTask);
180 	virtual IOReturn       clientClose(void) APPLE_KEXT_OVERRIDE;
181 	virtual bool           finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
182 	virtual void           stop(IOService * provider) APPLE_KEXT_OVERRIDE;
183 	virtual void           free() APPLE_KEXT_OVERRIDE;
184 
185 	virtual IOReturn       setProperties(OSObject * properties) APPLE_KEXT_OVERRIDE;
186 	virtual IOReturn       externalMethod(uint32_t selector, IOExternalMethodArguments * args,
187 	    IOExternalMethodDispatch * dispatch,
188 	    OSObject * target, void * reference) APPLE_KEXT_OVERRIDE;
189 
190 	virtual IOExternalTrap * getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) APPLE_KEXT_OVERRIDE;
191 
192 	IOReturn               serviceAttach(IOService * service, IOService * provider);
193 	IOReturn               serviceStop(IOService * service, IOService * provider);
194 	void                   serviceFree(IOService * service);
195 	IOReturn               serviceStarted(IOService * service, IOService * provider, bool result);
196 	static void            serviceWillTerminate(IOService * client, IOService * provider, IOOptionBits options);
197 	static void            serviceDidTerminate(IOService * client, IOService * provider, IOOptionBits options, bool * defer);
198 	static void            serviceDidStop(IOService * client, IOService * provider);
199 	IOReturn               serviceOpen(IOService * provider, IOService * client);
200 	IOReturn               serviceClose(IOService * provider, IOService * client);
201 	IOReturn               serviceSetPowerState(IOService * controllingDriver, IOService * service, IOPMPowerFlags flags, IOPMPowerStateIndex powerState);
202 	IOReturn               serviceNewUserClient(IOService * service, task_t owningTask, void * securityID,
203 	    uint32_t type, OSDictionary * properties, IOUserClient ** handler);
204 	IOReturn               serviceNewUserClient(IOService * service, task_t owningTask, void * securityID,
205 	    uint32_t type, OSDictionary * properties, OSSharedPtr<IOUserClient>& handler);
206 	IOReturn               exit(const char * reason);
207 
208 	bool                   serviceMatchesCheckInToken(IOUserServerCheckInToken *token);
209 	bool                   checkEntitlements(IOService * provider, IOService * dext);
210 	bool                   checkEntitlements(OSDictionary * entitlements, LIBKERN_CONSUMED OSObject * prop,
211 	    IOService * provider, IOService * dext);
212 
213 	void                   setTaskLoadTag(OSKext *kext);
214 	void                   setDriverKitUUID(OSKext *kext);
215 	void                   setCheckInToken(IOUserServerCheckInToken *token);
216 	void                   systemPower(bool powerOff);
217 	void                               systemHalt(int howto);
218 	static void            powerSourceChanged(bool acAttached);
219 
220 	IOReturn                                setPowerState(unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
221 	IOReturn                                powerStateWillChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
222 	IOReturn                                powerStateDidChangeTo(IOPMPowerFlags flags, unsigned long state, IOService * service) APPLE_KEXT_OVERRIDE;
223 
224 	IOPStrings *           copyInStringArray(const char * string, uint32_t userSize);
225 	uint32_t               stringArrayIndex(IOPStrings * array, const char * look);
226 	IOReturn               registerClass(OSClassDescription * desc, uint32_t size, OSUserMetaClass ** cls);
227 	IOReturn               registerClass(OSClassDescription * desc, uint32_t size, OSSharedPtr<OSUserMetaClass>& cls);
228 	IOReturn               setRootQueue(IODispatchQueue * queue);
229 
230 	OSObjectUserVars     * varsForObject(OSObject * obj);
231 	LIBKERN_RETURNS_NOT_RETAINED IODispatchQueue      * queueForObject(OSObject * obj, uint64_t msgid);
232 
233 	static ipc_port_t      copySendRightForObject(OSObject * object, natural_t /* ipc_kobject_type_t */ type);
234 	static OSObject      * copyObjectForSendRight(ipc_port_t port, natural_t /* ipc_kobject_type_t */ type);
235 
236 	IOReturn               copyOutObjects(IORPCMessageMach * mach, IORPCMessage * message,
237 	    size_t size, bool consume);
238 	IOReturn               copyInObjects(IORPCMessageMach * mach, IORPCMessage * message,
239 	    size_t size, bool copyObjects, bool consumePorts);
240 
241 	IOReturn               consumeObjects(IORPCMessage * message, size_t messageSize);
242 
243 	IOReturn               objectInstantiate(OSObject * obj, IORPC rpc, IORPCMessage * message);
244 	IOReturn               kernelDispatch(OSObject * obj, IORPC rpc);
245 	static OSObject      * target(OSAction * action, IORPCMessage * message);
246 
247 	IOReturn               rpc(IORPC rpc);
248 	IOReturn               server(ipc_kmsg_t requestkmsg, ipc_kmsg_t * preply);
249 	kern_return_t          waitInterruptTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6);
250 };
251 
252 typedef void (*IOUserServerCheckInCancellationHandler)(class IOUserServerCheckInToken*, void*);
253 
254 // OSObject wrapper around IOUserServerCheckInCancellationHandler
255 class _IOUserServerCheckInCancellationHandler : public OSObject {
256 	OSDeclareDefaultStructors(_IOUserServerCheckInCancellationHandler);
257 public:
258 	static _IOUserServerCheckInCancellationHandler *
259 	withHandler(IOUserServerCheckInCancellationHandler handler, void * args);
260 
261 	void call(IOUserServerCheckInToken * token);
262 private:
263 	IOUserServerCheckInCancellationHandler fHandler;
264 	void                                 * fHandlerArgs;
265 };
266 
267 class IOUserServerCheckInToken : public OSObject
268 {
269 	enum State {
270 		kIOUserServerCheckInPending,
271 		kIOUserServerCheckInCanceled,
272 		kIOUserServerCheckInComplete,
273 	};
274 
275 	OSDeclareDefaultStructors(IOUserServerCheckInToken);
276 public:
277 	virtual void free() APPLE_KEXT_OVERRIDE;
278 
279 	/*
280 	 * Cancel all pending dext launches.
281 	 */
282 	static void cancelAll();
283 
284 	/*
285 	 * Set handler to be invoked when launch is cancelled. Returns an wrapper object for the handler to be released by the caller.
286 	 * The handler always runs under the lock for this IOUserServerCheckInToken.
287 	 * The returned object can be used with removeCancellationHandler().
288 	 */
289 	_IOUserServerCheckInCancellationHandler * setCancellationHandler(IOUserServerCheckInCancellationHandler handler, void *handlerArgs);
290 
291 	/*
292 	 * Remove previously set cancellation handler.
293 	 */
294 	void removeCancellationHandler(_IOUserServerCheckInCancellationHandler * handler);
295 
296 	/*
297 	 * Cancel the launch
298 	 */
299 	void cancel();
300 
301 	/*
302 	 * Mark launch as completed.
303 	 */
304 	void complete();
305 
306 	const OSSymbol * copyServerName() const;
307 	OSNumber * copyServerTag() const;
308 
309 private:
310 	static IOUserServerCheckInToken * findExistingToken(const OSSymbol * serverName);
311 	bool init(const OSSymbol * userServerName, OSNumber * serverTag);
312 
313 	friend class IOUserServer;
314 
315 
316 
317 private:
318 	IOUserServerCheckInToken::State          fState;
319 	size_t                                   fPendingCount;
320 	const OSSymbol                         * fServerName;
321 	OSNumber                               * fServerTag;
322 	OSSet                                  * fHandlers;
323 };
324 
325 extern "C" kern_return_t
326 IOUserServerUEXTTrap(OSObject * object, void * p1, void * p2, void * p3, void * p4, void * p5, void * p6);
327 
328 #endif /* XNU_KERNEL_PRIVATE */
329 #endif /* _IOUSERSERVER_H */
330