ioctl_private.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <exception.h>
23 #include <ioctl_private.h>
24 #include <driver_entry_interface.h>
25 
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <sys/ioctl.h>
29 
30 // -----------------------------------------------------------------------------
31 // Unit Test Seems
32 // -----------------------------------------------------------------------------
33 
34 int64_t
36 {
37  return 5;
38 }
39 
40 int64_t
41 bf_send_ioctl(int64_t fd, unsigned long request)
42 {
43  (void)fd;
44  (void)request;
45 
46  return 0;
47 }
48 
49 int64_t
50 bf_read_ioctl(int64_t fd, unsigned long request, void *data)
51 {
52  (void)fd;
53  (void)request;
54  (void)data;
55 
56  return 0;
57 }
58 
59 int64_t
60 bf_write_ioctl(int64_t fd, unsigned long request, const void *data)
61 {
62  (void)fd;
63  (void)request;
64  (void)data;
65 
66  return 0;
67 }
68 
69 // -----------------------------------------------------------------------------
70 // Implementation
71 // -----------------------------------------------------------------------------
72 
74 {
75 }
76 
78 {
79  IOServiceClose(m_connect);
80 }
81 
82 void ioctl_private::ioctl_write(bf_ioctl_t *in, bf_ioctl_t *out)
83 {
84  size_t inStructSize = sizeof(bf_ioctl_t);
85  size_t outStructSize = sizeof(bf_ioctl_t);
86 
87  // Send the message to the kernel.
88  IOConnectCallStructMethod(m_connect, 1, in, inStructSize, out, &outStructSize);
89 }
90 
91 void ioctl_private::ioctl_read(bf_ioctl_t *in, bf_ioctl_t *out)
92 {
93  size_t inStructSize = sizeof(bf_ioctl_t);
94  size_t outStructSize = sizeof(bf_ioctl_t);
95 
96  // Send the message to the kernel.
97  IOConnectCallStructMethod(m_connect, 1, in, inStructSize, out, &outStructSize);
98 }
99 #include <iostream>
100 void
102 {
103  io_iterator_t iterator;
104  io_service_t service;
105  kern_return_t kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("org_bareflank_osx"), &iterator);
106 
107  // Make sure the service was located.
108  if (kernResult != KERN_SUCCESS)
109  {
110  throw unknown_command("IOServiceGetMatchingServices failed.\n");
111  }
112 
113  // Get the service from the criteria listed above.
114  if ((service = IOIteratorNext(iterator)) != IO_OBJECT_NULL)
115  {
116 
117  // Now that the service is located, setup a connection to that service.
118  kernResult = IOServiceOpen(service, mach_task_self(), 0, &m_connect);
119 
120  // Make sure a connection was made.
121  if (kernResult != KERN_SUCCESS)
122  {
123 
124  throw unknown_command("Unabled to get handle to the driver.\n");
125  }
126  }
127 }
128 
129 int64_t
130 ioctl_private::bf_write_ioctl(int fd, uint32_t cmd, void *arg)
131 {
132  (void)fd;
133 
134  bf_ioctl_t in = { 0, 0, 0 };
135  bf_ioctl_t out = { 0, 0, 0 };
136 
137  in.command = cmd;
138  in.addr = arg;
139  in.size = 0;
140 
141  ioctl_write(&in, &out);
142 
143  return out.command;
144 }
145 
146 int64_t
147 ioctl_private::bf_read_ioctl(int fd, uint32_t cmd, void *arg)
148 {
149  (void)fd;
150 
151  bf_ioctl_t in = { 0, 0, 0 };
152  bf_ioctl_t out = { 0, 0, 0 };
153 
154  in.command = cmd;
155  in.addr = arg;
156  in.size = 0;
157 
158  ioctl_write(&in, &out);
159 
160  return out.command;
161 }
162 
163 int64_t
164 ioctl_private::bf_send_ioctl(int fd, uint32_t cmd)
165 {
166  (void)fd;
167 
168  bf_ioctl_t in = { 0, 0, 0 };
169  bf_ioctl_t out = { 0, 0, 0 };
170 
171  in.command = cmd;
172  in.addr = 0;
173  in.size = 0;
174 
175  ioctl_write(&in, &out);
176 
177  return out.command;
178 }
179 
180 
181 void
183 {
184  int fd = 0;
185 
186  if (len <= 0)
187  throw unknown_command("len <= 0");
188 
189  if (bf_write_ioctl(fd, IOCTL_ADD_MODULE_LENGTH, &len) < 0)
190  throw ioctl_failed(IOCTL_ADD_MODULE_LENGTH);
191 }
192 
193 void
195 {
196  int fd = 0;
197 
198  if (data == nullptr)
199  throw unknown_command("data == NULL");
200 
201  if (bf_write_ioctl(fd, IOCTL_ADD_MODULE, (void *)data) < 0)
202  throw ioctl_failed(IOCTL_ADD_MODULE);
203 }
204 
205 void
207 {
208  int fd = 0;
209 
210  if (bf_send_ioctl(fd, IOCTL_LOAD_VMM) < 0)
211  throw ioctl_failed(IOCTL_LOAD_VMM);
212 }
213 
214 void
216 {
217  int fd = 0;
218 
219  if (bf_send_ioctl(fd, IOCTL_UNLOAD_VMM) < 0)
220  throw ioctl_failed(IOCTL_UNLOAD_VMM);
221 }
222 
223 void
225 {
226  int fd = 0;
227 
228  if (bf_send_ioctl(fd, IOCTL_START_VMM) < 0)
229  throw ioctl_failed(IOCTL_START_VMM);
230 }
231 
232 void
234 {
235  int fd = 0;
236 
237  if (bf_send_ioctl(fd, IOCTL_STOP_VMM) < 0)
238  throw ioctl_failed(IOCTL_STOP_VMM);
239 }
240 
241 void
243 {
244  int fd = 0;
245 
246  if (drr == nullptr)
247  throw unknown_command("drr == NULL");
248 
249  if (bf_read_ioctl(fd, IOCTL_DUMP_VMM, drr) < 0)
250  throw ioctl_failed(IOCTL_DUMP_VMM);
251 }
252 
253 void
255 {
256  int fd = 0;
257 
258  if (status == nullptr)
259  throw unknown_command("status == NULL");
260 
261  if (bf_read_ioctl(fd, IOCTL_VMM_STATUS, status) < 0)
262  throw ioctl_failed(IOCTL_VMM_STATUS);
263 }
virtual void call_ioctl_stop_vmm()
int64_t unsigned long request
int64_t bf_read_ioctl(int64_t fd, unsigned long request, void *data)
int64_t bf_ioctl_open()
virtual void call_ioctl_load_vmm()
int64_t unsigned long void * data
virtual void call_ioctl_add_module_length(module_len_type len)
virtual void call_ioctl_vmm_status(gsl::not_null< status_pointer > status)
debug_ring_resources_t * drr
virtual void call_ioctl_start_vmm()
virtual void call_ioctl_dump_vmm(gsl::not_null< drr_pointer > drr, vcpuid_type vcpuid)
int64_t bf_write_ioctl(int64_t fd, unsigned long request, const void *data)
#define ioctl_failed(a)
Definition: exception.h:262
~ioctl_private() override
virtual void call_ioctl_add_module(gsl::not_null< module_data_type > data)
virtual void open()
int64_t bf_send_ioctl(int64_t fd, unsigned long request)
virtual void call_ioctl_unload_vmm()
#define unknown_command(a)
Definition: exception.h:130