1 // Copyright 2018 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 #include <err.h>
8 #include <inttypes.h>
9 
10 #include <lib/counters.h>
11 #include <lib/ktrace.h>
12 
13 #include <object/handle.h>
14 #include <object/job_dispatcher.h>
15 #include <object/profile_dispatcher.h>
16 
17 #include <zircon/types.h>
18 
19 #include <fbl/ref_ptr.h>
20 
21 #include "priv.h"
22 
23 KCOUNTER(profile_create, "kernel.profile.create");
24 KCOUNTER(profile_set,    "kernel.profile.set");
25 
26 
27 // zx_status_t zx_profile_create
sys_profile_create(zx_handle_t root_job,user_in_ptr<const zx_profile_info_t> user_profile_info,user_out_handle * out)28 zx_status_t sys_profile_create(zx_handle_t root_job,
29                                user_in_ptr<const zx_profile_info_t> user_profile_info,
30                                user_out_handle* out) {
31     // TODO(cpu): check job policy.
32 
33     auto up = ProcessDispatcher::GetCurrent();
34 
35     fbl::RefPtr<JobDispatcher> job;
36     auto status = up->GetDispatcherWithRights(root_job, ZX_RIGHT_MANAGE_PROCESS, &job);
37     if (status != ZX_OK)
38         return status;
39 
40     // Validate that the job is in fact the first usermode job (aka root job).
41     if (GetRootJobDispatcher() != job->parent()) {
42         // TODO(cpu): consider a better error code.
43         return ZX_ERR_ACCESS_DENIED;
44     }
45 
46     zx_profile_info_t profile_info;
47     status = user_profile_info.copy_from_user(&profile_info);
48     if (status != ZX_OK)
49         return status;
50 
51     fbl::RefPtr<Dispatcher> dispatcher;
52     zx_rights_t rights;
53     status = ProfileDispatcher::Create(profile_info, &dispatcher, &rights);
54     if (status != ZX_OK)
55         return status;
56 
57     return out->make(ktl::move(dispatcher), rights);
58 }
59 
60 // zx_status_t zx_object_set_profile
sys_object_set_profile(zx_handle_t handle,zx_handle_t profile_handle,uint32_t options)61 zx_status_t sys_object_set_profile(zx_handle_t handle,
62                                    zx_handle_t profile_handle,
63                                    uint32_t options) {
64     auto up = ProcessDispatcher::GetCurrent();
65 
66     // TODO(cpu): support more than thread objects, and actually do something.
67 
68     fbl::RefPtr<ThreadDispatcher> thread;
69     auto status = up->GetDispatcherWithRights(handle, ZX_RIGHT_MANAGE_THREAD, &thread);
70     if (status != ZX_OK)
71         return status;
72 
73     fbl::RefPtr<ProfileDispatcher> profile;
74     zx_status_t result =
75         up->GetDispatcherWithRights(profile_handle, ZX_RIGHT_APPLY_PROFILE, &profile);
76     if (result != ZX_OK)
77         return result;
78 
79     return profile->ApplyProfile(ktl::move(thread));
80 }
81