vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / busses / random / virtio_rng.cpp
blob951c4eb14933a83021ab5ba2e1f6f401a23a6f0e
1 /*
2 * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "VirtioRNGPrivate.h"
9 #include <new>
10 #include <stdlib.h>
11 #include <string.h>
14 #define VIRTIO_RNG_CONTROLLER_PRETTY_NAME "Virtio RNG Device"
16 #define VIRTIO_RNG_DRIVER_MODULE_NAME "busses/random/virtio_rng/driver_v1"
17 #define VIRTIO_RNG_DEVICE_MODULE_NAME "busses/random/virtio_rng/device_v1"
20 device_manager_info *gDeviceManager;
21 random_for_controller_interface *gRandom;
24 // #pragma mark - Random module interface
27 static status_t
28 sim_init_bus(device_node *node, void **_cookie)
30 CALLED();
32 VirtioRNGDevice *device = new(std::nothrow)
33 VirtioRNGDevice(node);
34 if (device == NULL)
35 return B_NO_MEMORY;
36 status_t status = device->InitCheck();
37 if (status < B_OK) {
38 delete device;
39 return status;
42 *_cookie = device;
43 return B_OK;
47 static void
48 sim_uninit_bus(void *cookie)
50 CALLED();
51 VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
53 delete device;
57 static status_t
58 sim_read(void* cookie, void *_buffer, size_t *_numBytes)
60 VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
61 return device->Read(_buffer, _numBytes);
65 // #pragma mark - Driver module interface
68 static float
69 virtio_rng_supports_device(device_node *parent)
71 const char *bus;
72 uint16 deviceType;
74 // make sure parent is really the Virtio bus manager
75 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
76 return -1;
78 if (strcmp(bus, "virtio"))
79 return 0.0;
81 // check whether it's really a Virtio Entropy Device
82 if (gDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM,
83 &deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_ENTROPY)
84 return 0.0;
86 TRACE("Virtio RNG device found!\n");
88 return 0.6f;
92 static status_t
93 virtio_rng_register_device(device_node *parent)
95 CALLED();
97 device_attr attrs[] = {
98 { NULL }
101 return gDeviceManager->register_node(parent, VIRTIO_RNG_DRIVER_MODULE_NAME,
102 attrs, NULL, NULL);
106 static status_t
107 virtio_rng_init_driver(device_node *node, void **_cookie)
109 CALLED();
110 *_cookie = node;
111 return B_OK;
115 static status_t
116 virtio_rng_register_child_devices(void *cookie)
118 CALLED();
119 device_node *node = (device_node *)cookie;
121 device_attr attrs[] = {
122 { B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
123 { string: RANDOM_FOR_CONTROLLER_MODULE_NAME }},
124 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
125 { string: VIRTIO_RNG_CONTROLLER_PRETTY_NAME }},
126 { NULL }
129 return gDeviceManager->register_node(node,
130 VIRTIO_RNG_DEVICE_MODULE_NAME, attrs, NULL, NULL);
134 static status_t
135 std_ops(int32 op, ...)
137 switch (op) {
138 case B_MODULE_INIT:
139 case B_MODULE_UNINIT:
140 return B_OK;
142 default:
143 return B_ERROR;
148 static random_module_info sVirtioRNGDeviceInterface = {
151 VIRTIO_RNG_DEVICE_MODULE_NAME,
153 std_ops
155 NULL, // supported devices
156 NULL, // register node
157 sim_init_bus,
158 sim_uninit_bus,
159 NULL, // register child devices
160 NULL, // rescan
161 NULL // bus_removed
164 sim_read,
165 NULL // write
170 static driver_module_info sVirtioRNGDriver = {
172 VIRTIO_RNG_DRIVER_MODULE_NAME,
174 std_ops
176 virtio_rng_supports_device,
177 virtio_rng_register_device,
178 virtio_rng_init_driver,
179 NULL, // uninit_driver,
180 virtio_rng_register_child_devices,
181 NULL, // rescan
182 NULL, // device_removed
186 module_dependency module_dependencies[] = {
187 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
188 { RANDOM_FOR_CONTROLLER_MODULE_NAME, (module_info **)&gRandom },
193 module_info *modules[] = {
194 (module_info *)&sVirtioRNGDriver,
195 (module_info *)&sVirtioRNGDeviceInterface,
196 NULL