1 // Copyright 2016 The Fuchsia Authors 2 // 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file or at 5 // https://opensource.org/licenses/MIT 6 7 #pragma once 8 9 #include <kernel/event.h> 10 #include <kernel/thread.h> 11 #include <object/dispatcher.h> 12 #include <object/futex_context.h> 13 #include <object/handle.h> 14 #include <object/job_policy.h> 15 #include <object/thread_dispatcher.h> 16 #include <vm/vm_aspace.h> 17 18 #include <zircon/syscalls/object.h> 19 #include <zircon/types.h> 20 #include <fbl/array.h> 21 #include <fbl/canary.h> 22 #include <fbl/intrusive_double_list.h> 23 #include <fbl/mutex.h> 24 #include <fbl/name.h> 25 #include <fbl/ref_counted.h> 26 #include <fbl/ref_ptr.h> 27 #include <fbl/string_piece.h> 28 29 class JobDispatcher; 30 31 class ProcessDispatcher final 32 : public SoloDispatcher<ProcessDispatcher, ZX_DEFAULT_PROCESS_RIGHTS> { 33 public: 34 static zx_status_t Create( 35 fbl::RefPtr<JobDispatcher> job, fbl::StringPiece name, uint32_t flags, 36 fbl::RefPtr<Dispatcher>* dispatcher, zx_rights_t* rights, 37 fbl::RefPtr<VmAddressRegionDispatcher>* root_vmar_disp, 38 zx_rights_t* root_vmar_rights); 39 40 // Traits to belong in the parent job's raw list. 41 struct JobListTraitsRaw { node_stateJobListTraitsRaw42 static fbl::DoublyLinkedListNodeState<ProcessDispatcher*>& node_state( 43 ProcessDispatcher& obj) { 44 return obj.dll_job_raw_; 45 } 46 }; 47 48 // Traits to belong in the parent job's list. 49 struct JobListTraits { node_stateJobListTraits50 static fbl::SinglyLinkedListNodeState<fbl::RefPtr<ProcessDispatcher>>& node_state( 51 ProcessDispatcher& obj) { 52 return obj.dll_job_; 53 } 54 }; 55 GetCurrent()56 static ProcessDispatcher* GetCurrent() { 57 ThreadDispatcher* current = ThreadDispatcher::GetCurrent(); 58 DEBUG_ASSERT(current); 59 return current->process(); 60 } 61 62 // Dispatcher implementation get_type()63 zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_PROCESS; } 64 void on_zero_handles() final; 65 zx_koid_t get_related_koid() const final; 66 67 ~ProcessDispatcher() final; 68 69 // state of the process 70 enum class State { 71 INITIAL, // initial state, no thread present in process 72 RUNNING, // first thread has started and is running 73 DYING, // process has delivered kill signal to all threads 74 DEAD, // all threads have entered DEAD state and potentially dropped refs on process 75 }; 76 77 // Performs initialization on a newly constructed ProcessDispatcher 78 // If this fails, then the object is invalid and should be deleted 79 zx_status_t Initialize(); 80 81 // Maps a |handle| to an integer which can be given to usermode as a 82 // handle value. Uses Handle->base_value() plus additional mixing. 83 zx_handle_t MapHandleToValue(const Handle* handle) const; 84 zx_handle_t MapHandleToValue(const HandleOwner& handle) const; 85 86 // Maps a handle value into a Handle as long we can verify that 87 // it belongs to this process. Use |skip_policy = true| for testing that 88 // a handle is valid without potentially triggering a job policy exception. 89 Handle* GetHandleLocked( 90 zx_handle_t handle_value, bool skip_policy = false) TA_REQ(handle_table_lock_); 91 92 // Adds |handle| to this process handle list. The handle->process_id() is 93 // set to this process id(). 94 void AddHandle(HandleOwner handle); 95 void AddHandleLocked(HandleOwner handle) TA_REQ(handle_table_lock_); 96 97 // Removes the Handle corresponding to |handle_value| from this process 98 // handle list. 99 HandleOwner RemoveHandle(zx_handle_t handle_value); 100 HandleOwner RemoveHandleLocked(zx_handle_t handle_value) TA_REQ(handle_table_lock_); 101 102 // Remove all of an array of |user_handles| from the 103 // process. Returns ZX_OK if all of the handles were removed, and 104 // returns ZX_ERR_BAD_HANDLE if any were not. 105 zx_status_t RemoveHandles(user_in_ptr<const zx_handle_t> user_handles, 106 size_t num_handles); 107 108 // Get the dispatcher corresponding to this handle value. 109 template <typename T> GetDispatcher(zx_handle_t handle_value,fbl::RefPtr<T> * dispatcher)110 zx_status_t GetDispatcher(zx_handle_t handle_value, 111 fbl::RefPtr<T>* dispatcher) { 112 return GetDispatcherAndRights(handle_value, dispatcher, nullptr); 113 } 114 115 // Get the dispatcher and the rights corresponding to this handle value. 116 template <typename T> GetDispatcherAndRights(zx_handle_t handle_value,fbl::RefPtr<T> * dispatcher,zx_rights_t * out_rights)117 zx_status_t GetDispatcherAndRights(zx_handle_t handle_value, 118 fbl::RefPtr<T>* dispatcher, 119 zx_rights_t* out_rights) { 120 fbl::RefPtr<Dispatcher> generic_dispatcher; 121 auto status = GetDispatcherInternal(handle_value, &generic_dispatcher, out_rights); 122 if (status != ZX_OK) 123 return status; 124 *dispatcher = DownCastDispatcher<T>(&generic_dispatcher); 125 if (!*dispatcher) 126 return ZX_ERR_WRONG_TYPE; 127 return ZX_OK; 128 } 129 130 // Get the dispatcher corresponding to this handle value, after 131 // checking that this handle has the desired rights. 132 // Returns the rights the handle currently has. 133 template <typename T> GetDispatcherWithRights(zx_handle_t handle_value,zx_rights_t desired_rights,fbl::RefPtr<T> * dispatcher,zx_rights_t * out_rights)134 zx_status_t GetDispatcherWithRights(zx_handle_t handle_value, 135 zx_rights_t desired_rights, 136 fbl::RefPtr<T>* dispatcher, 137 zx_rights_t* out_rights) { 138 fbl::RefPtr<Dispatcher> generic_dispatcher; 139 auto status = GetDispatcherWithRightsInternal(handle_value, 140 desired_rights, 141 &generic_dispatcher, 142 out_rights); 143 if (status != ZX_OK) 144 return status; 145 *dispatcher = DownCastDispatcher<T>(&generic_dispatcher); 146 if (!*dispatcher) 147 return ZX_ERR_WRONG_TYPE; 148 return ZX_OK; 149 } 150 151 // Get the dispatcher corresponding to this handle value, after 152 // checking that this handle has the desired rights. 153 template <typename T> GetDispatcherWithRights(zx_handle_t handle_value,zx_rights_t desired_rights,fbl::RefPtr<T> * dispatcher)154 zx_status_t GetDispatcherWithRights(zx_handle_t handle_value, 155 zx_rights_t desired_rights, 156 fbl::RefPtr<T>* dispatcher) { 157 return GetDispatcherWithRights(handle_value, desired_rights, dispatcher, nullptr); 158 } 159 160 zx_koid_t GetKoidForHandle(zx_handle_t handle_value); 161 162 bool IsHandleValid(zx_handle_t handle_value); 163 bool IsHandleValidNoPolicyCheck(zx_handle_t handle_value); 164 165 // Calls the provided 166 // |zx_status_t func(zx_handle_t, zx_rights_t, fbl::RefPtr<Dispatcher>)| 167 // on every handle owned by the process. Stops if |func| returns an error, 168 // returning the error value. 169 template <typename T> ForEachHandle(T func)170 zx_status_t ForEachHandle(T func) const { 171 Guard<fbl::Mutex> guard{&handle_table_lock_}; 172 for (const auto& handle : handles_) { 173 const Dispatcher* dispatcher = handle.dispatcher().get(); 174 zx_status_t s = func(MapHandleToValue(&handle), handle.rights(), 175 dispatcher); 176 if (s != ZX_OK) { 177 return s; 178 } 179 } 180 return ZX_OK; 181 } 182 183 // accessors handle_table_lock()184 Lock<fbl::Mutex>* handle_table_lock() TA_RET_CAP(handle_table_lock_) { 185 return &handle_table_lock_; 186 } futex_context()187 FutexContext* futex_context() { return &futex_context_; } 188 State state() const; aspace()189 fbl::RefPtr<VmAspace> aspace() { return aspace_; } 190 fbl::RefPtr<JobDispatcher> job(); 191 192 void get_name(char out_name[ZX_MAX_NAME_LEN]) const final; 193 zx_status_t set_name(const char* name, size_t len) final; 194 195 void Exit(int64_t retcode) __NO_RETURN; 196 void Kill(); 197 198 // Suspends the process. 199 // 200 // Suspending a process causes all child threads to suspend as well as any new children 201 // that are added until the process is resumed. Suspend() is cumulative, so the process 202 // will only resume once Resume() has been called an equal number of times. 203 // 204 // Returns ZX_OK on success, or ZX_ERR_BAD_STATE iff the process is dying or dead. 205 zx_status_t Suspend(); 206 void Resume(); 207 208 // Syscall helpers 209 zx_status_t GetInfo(zx_info_process_t* info); 210 zx_status_t GetStats(zx_info_task_stats_t* stats); 211 // NOTE: Code outside of the syscall layer should not typically know about 212 // user_ptrs; do not use this pattern as an example. 213 zx_status_t GetAspaceMaps(user_out_ptr<zx_info_maps_t> maps, size_t max, 214 size_t* actual, size_t* available); 215 zx_status_t GetVmos(user_out_ptr<zx_info_vmo_t> vmos, size_t max, 216 size_t* actual, size_t* available); 217 218 zx_status_t GetThreads(fbl::Array<zx_koid_t>* threads); 219 220 // exception handling support 221 zx_status_t SetExceptionPort(fbl::RefPtr<ExceptionPort> eport); 222 // Returns true if a port had been set. 223 bool ResetExceptionPort(bool debugger); 224 fbl::RefPtr<ExceptionPort> exception_port(); 225 fbl::RefPtr<ExceptionPort> debugger_exception_port(); 226 // |eport| can either be the process's eport or that of any parent job. 227 void OnExceptionPortRemoval(const fbl::RefPtr<ExceptionPort>& eport); 228 229 // The following two methods can be slow and inaccurate and should only be 230 // called from diagnostics code. 231 uint32_t ThreadCount() const; 232 size_t PageCount() const; 233 234 // Look up a process given its koid. 235 // Returns nullptr if not found. 236 static fbl::RefPtr<ProcessDispatcher> LookupProcessById(zx_koid_t koid); 237 238 // Look up a thread in this process given its koid. 239 // Returns nullptr if not found. 240 fbl::RefPtr<ThreadDispatcher> LookupThreadById(zx_koid_t koid); 241 242 uintptr_t get_debug_addr() const; 243 zx_status_t set_debug_addr(uintptr_t addr); 244 245 // Checks the |condition| against the parent job's policy. 246 // 247 // Must be called by syscalls before performing an action represented by an 248 // ZX_POL_xxxxx condition. If the return value is ZX_OK the action can 249 // proceed; otherwise, the process is not allowed to perform the action, 250 // and the status value should be returned to the usermode caller. 251 // 252 // E.g., in sys_channel_create: 253 // 254 // auto up = ProcessDispatcher::GetCurrent(); 255 // zx_status_t res = up->QueryBasicPolicy(ZX_POL_NEW_CHANNEL); 256 // if (res != ZX_OK) { 257 // // Channel creation denied by the calling process's 258 // // parent job's policy. 259 // return res; 260 // } 261 // // Ok to create a channel. 262 zx_status_t QueryBasicPolicy(uint32_t condition) const; 263 264 // Returns this job's timer slack policy. 265 TimerSlack GetTimerSlackPolicy() const; 266 267 // return a cached copy of the vdso code address or compute a new one vdso_code_address()268 uintptr_t vdso_code_address() { 269 if (unlikely(vdso_code_address_ == 0)) { 270 return cache_vdso_code_address(); 271 } 272 return vdso_code_address_; 273 } 274 275 private: 276 // compute the vdso code address and store in vdso_code_address_ 277 uintptr_t cache_vdso_code_address(); 278 279 // The diagnostic code is allow to know about the internals of this code. 280 friend void DumpProcessList(); 281 friend void KillProcess(zx_koid_t id); 282 friend void DumpProcessMemoryUsage(const char* prefix, size_t min_pages); 283 284 ProcessDispatcher(fbl::RefPtr<JobDispatcher> job, fbl::StringPiece name, uint32_t flags); 285 286 ProcessDispatcher(const ProcessDispatcher&) = delete; 287 ProcessDispatcher& operator=(const ProcessDispatcher&) = delete; 288 289 290 zx_status_t GetDispatcherInternal(zx_handle_t handle_value, fbl::RefPtr<Dispatcher>* dispatcher, 291 zx_rights_t* rights); 292 293 zx_status_t GetDispatcherWithRightsInternal(zx_handle_t handle_value, zx_rights_t desired_rights, 294 fbl::RefPtr<Dispatcher>* dispatcher_out, 295 zx_rights_t* out_rights); 296 297 void OnProcessStartForJobDebugger(ThreadDispatcher *t); 298 299 // Thread lifecycle support. 300 // 301 // |suspended| indicates whether the parent process is currently suspended or not. If true, 302 // the child thread must increment its own suspend count by one and transition to suspend. 303 friend class ThreadDispatcher; 304 zx_status_t AddThread(ThreadDispatcher* t, bool initial_thread, bool* suspended); 305 void RemoveThread(ThreadDispatcher* t); 306 307 void SetStateLocked(State) TA_REQ(get_lock()); 308 void FinishDeadTransition(); 309 310 // Kill all threads 311 void KillAllThreadsLocked() TA_REQ(get_lock()); 312 313 // TODO(dbort): Add "canary_.Assert()" calls to methods. 314 fbl::Canary<fbl::magic("PROC")> canary_; 315 316 // the enclosing job 317 const fbl::RefPtr<JobDispatcher> job_; 318 319 // Policy set by the Job during Create(). 320 // 321 // It is critical that this field is immutable as it will be accessed without synchronization. 322 const JobPolicy policy_; 323 324 // The process can belong to either of these lists independently. 325 fbl::DoublyLinkedListNodeState<ProcessDispatcher*> dll_job_raw_; 326 fbl::SinglyLinkedListNodeState<fbl::RefPtr<ProcessDispatcher>> dll_job_; 327 328 uint32_t handle_rand_ = 0; 329 330 // list of threads in this process 331 using ThreadList = fbl::DoublyLinkedList<ThreadDispatcher*, ThreadDispatcher::ThreadListTraits>; 332 ThreadList thread_list_ TA_GUARDED(get_lock()); 333 334 // our address space 335 fbl::RefPtr<VmAspace> aspace_; 336 337 // our list of handles 338 mutable DECLARE_MUTEX(ProcessDispatcher) handle_table_lock_; // protects |handles_|. 339 fbl::DoublyLinkedList<Handle*> handles_ TA_GUARDED(handle_table_lock_); 340 341 FutexContext futex_context_; 342 343 // our state 344 State state_ TA_GUARDED(get_lock()) = State::INITIAL; 345 346 // Suspend count; incremented on Suspend(), decremented on Resume(). 347 int suspend_count_ TA_GUARDED(get_lock()) = 0; 348 349 // True if FinishDeadTransition has been called. 350 // This is used as a sanity check only. 351 bool completely_dead_ = false; 352 353 // process return code 354 int64_t retcode_ = 0; 355 356 // Exception ports bound to the process. 357 fbl::RefPtr<ExceptionPort> exception_port_ TA_GUARDED(get_lock()); 358 fbl::RefPtr<ExceptionPort> debugger_exception_port_ TA_GUARDED(get_lock()); 359 360 // This is the value of _dl_debug_addr from ld.so. 361 // See third_party/ulib/musl/ldso/dynlink.c. 362 uintptr_t debug_addr_ TA_GUARDED(get_lock()) = 0; 363 364 // This is a cache of aspace()->vdso_code_address(). 365 uintptr_t vdso_code_address_ = 0; 366 367 // The user-friendly process name. For debug purposes only. That 368 // is, there is no mechanism to mint a handle to a process via this name. 369 fbl::Name<ZX_MAX_NAME_LEN> name_; 370 }; 371 372 const char* StateToString(ProcessDispatcher::State state); 373