Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: src/trusted/plugin/srpc/shared_memory.cc

Issue 2981011: Move plugin/srpc contents to the more appropriately named plugin/common.... (Closed) Base URL: http://nativeclient.googlecode.com/svn/trunk/src/native_client/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/plugin/srpc/shared_memory.h ('k') | src/trusted/plugin/srpc/socket_address.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2008 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the LICENSE file.
5 */
6
7
8 #include <errno.h>
9 #include <signal.h>
10 #include <string.h>
11
12 #include "native_client/src/include/checked_cast.h"
13 #include "native_client/src/include/nacl_platform.h"
14
15 #include "native_client/src/shared/platform/nacl_host_desc.h"
16 #include "native_client/src/shared/imc/nacl_imc.h"
17
18 #include "native_client/src/trusted/plugin/srpc/plugin.h"
19 #include "native_client/src/trusted/plugin/srpc/shared_memory.h"
20 #include "native_client/src/trusted/plugin/srpc/utility.h"
21
22 #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
23 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
24 #include "native_client/src/trusted/service_runtime/internal_errno.h"
25 #include "native_client/src/trusted/service_runtime/sel_util.h"
26
27
28 namespace {
29
30 bool RpcRead(void* obj, plugin::SrpcParams* params) {
31 plugin::SharedMemory* shared_memory =
32 reinterpret_cast<plugin::SharedMemory*>(obj);
33 uint32_t offset;
34 uint32_t len;
35
36 // TODO(gregoryd) - the old code was able to handle both ints and doubles
37 // it should be handled in the marshalling code,
38 // otherwise the call will be rejected
39 if (params->ins()[0]->tag == NACL_SRPC_ARG_TYPE_DOUBLE) {
40 offset = static_cast<uint32_t>(params->ins()[0]->u.dval);
41 } else {
42 offset = static_cast<uint32_t>(params->ins()[0]->u.ival);
43 }
44
45 if (params->ins()[1]->tag == NACL_SRPC_ARG_TYPE_DOUBLE) {
46 len = static_cast<uint32_t>(params->ins()[1]->u.dval);
47 } else {
48 len = static_cast<uint32_t>(params->ins()[1]->u.ival);
49 }
50
51 // Ensure we will access valid addresses.
52 if (NULL == shared_memory->shm_addr()) {
53 params->set_exception_string("Shared memory not mapped");
54 return false;
55 }
56 if (offset + len < offset) {
57 params->set_exception_string("Offset + length overflows");
58 return false;
59 }
60 if (offset + len > shared_memory->shm_size()) {
61 params->set_exception_string(
62 "Offset + length overlaps end of shared memory");
63 return false;
64 }
65
66 // TODO(mseaborn): Change this function to use ByteStringAsUTF8().
67 // UTF-8 encoding may result in a 2x size increase at the most.
68 // TODO(sehr): should we do a pre-scan to get the real size?
69 uint32_t utf8_buffer_len = 2 * len;
70 if ((utf8_buffer_len < len) ||
71 (utf8_buffer_len + 1 < utf8_buffer_len)) {
72 // Unsigned overflow.
73 params->set_exception_string("len too large to hold requested UTF8 chars");
74 return false;
75 }
76
77 char* ret_string = reinterpret_cast<char*>(malloc(utf8_buffer_len + 1));
78 if (NULL == ret_string) {
79 params->set_exception_string("out of memory");
80 return false;
81 }
82
83 unsigned char* shm_addr =
84 reinterpret_cast<unsigned char*>(shared_memory->shm_addr()) + offset;
85 unsigned char* out = reinterpret_cast<unsigned char*>(ret_string);
86 // NPAPI wants length to be the number of bytes, not UTF-8 characters.
87 for (unsigned int i = 0; i < len; ++i) {
88 unsigned char c = *shm_addr;
89 if (c < 128) {
90 // Code results in a one byte encoding
91 *out = c;
92 ++out;
93 } else {
94 // Code results in a two byte encoding
95 out[0] = 0xc0 | (c >> 6);
96 out[1] = 0x80 | (c & 0x3f);
97 out += 2;
98 }
99 ++shm_addr;
100 }
101 // Terminate the result string with 0.
102 *out = 0;
103
104 params->outs()[0]->tag = NACL_SRPC_ARG_TYPE_STRING;
105 params->outs()[0]->u.sval = ret_string;
106
107 return true;
108 }
109
110 bool RpcWrite(void* obj, plugin::SrpcParams* params) {
111 plugin::SharedMemory* shared_memory =
112 reinterpret_cast<plugin::SharedMemory*>(obj);
113 uint32_t offset;
114 uint32_t len;
115
116 // TODO(gregoryd) - the old code was able to handle both ints and doubles
117 // it should be handled in the marshalling code,
118 // otherwise the call will be rejected
119 if (params->ins()[0]->tag == NACL_SRPC_ARG_TYPE_DOUBLE) {
120 offset = static_cast<uint32_t>(params->ins()[0]->u.dval);
121 } else {
122 offset = static_cast<uint32_t>(params->ins()[0]->u.ival);
123 }
124
125 if (params->ins()[1]->tag == NACL_SRPC_ARG_TYPE_DOUBLE) {
126 len = static_cast<uint32_t>(params->ins()[1]->u.dval);
127 } else {
128 len = static_cast<uint32_t>(params->ins()[1]->u.ival);
129 }
130
131 // Ensure we will access valid addresses.
132 if (NULL == shared_memory->shm_addr()) {
133 params->set_exception_string("Shared memory not mapped");
134 return false;
135 }
136 if (offset + len < offset) {
137 params->set_exception_string("Offset + length overflows");
138 return false;
139 }
140 if (offset + len > shared_memory->shm_size()) {
141 params->set_exception_string(
142 "Offset + length overlaps end of shared memory");
143 return false;
144 }
145
146 // The input is a JavaScript string, which must consist of UFT-8
147 // characters with character codes between 0 and 255 inclusive.
148 NaClSrpcArg* str_param = params->ins()[2];
149 const unsigned char* str =
150 reinterpret_cast<unsigned const char*>(str_param->u.sval);
151 uint32_t utf_bytes = nacl::saturate_cast<uint32_t>(strlen(str_param->u.sval));
152 unsigned char* shm_addr =
153 reinterpret_cast<unsigned char*>(shared_memory->shm_addr()) + offset;
154
155 // TODO(mseaborn): Change this function to use ByteStringFromUTF8().
156 for (unsigned int i = 0; i < len;) {
157 unsigned char c1 = str[0];
158 unsigned char c2 = 0;
159
160 // Check that we are still pointing into the JavaScript string we were
161 // passed.
162 if (i >= utf_bytes) {
163 return false;
164 }
165 // Process the byte in the string as UTF-8 characters.
166 if (c1 & 0x80) {
167 // str[1] will not access out of bounds because sval is a NUL-terminated
168 // sequence of bytes. However, NUL would fail the content test just
169 // below, so failing here seems a good thing anyway.
170 if (i == len - 1) {
171 return false;
172 }
173 c2 = str[1];
174 // Assert two byte encoding.
175 // The first character must contain 110xxxxxb and the
176 // second must contain 10xxxxxxb.
177 if (((c1 & 0xc3) != c1) || ((c2 & 0xbf) != c2)) {
178 params->set_exception_string("Bad utf8 character value");
179 return false;
180 }
181 *shm_addr = (c1 << 6) | (c2 & 0x3f);
182 str += 2;
183 i += 2;
184 } else {
185 // One-byte encoding.
186 *shm_addr = c1;
187 ++str;
188 ++i;
189 }
190 ++shm_addr;
191 }
192 return true;
193 }
194
195 } // namespace
196
197 namespace plugin {
198
199 void SharedMemory::LoadMethods() {
200 AddMethodCall(RpcRead, "read", "ii", "s");
201 AddMethodCall(RpcWrite, "write", "iis", "");
202 }
203
204 bool SharedMemory::Init(Plugin* plugin,
205 nacl::DescWrapper* wrapper,
206 off_t length) {
207 bool allocated_memory = false;
208
209 if (NULL == wrapper) {
210 // Creating a new object by size
211 size_t size = static_cast<size_t>(length);
212 // The Map virtual function rounds up to the nearest AllocPage.
213 size_t rounded_size = NaClRoundAllocPage(size);
214 wrapper = plugin->wrapper_factory()->MakeShm(rounded_size);
215 if (NULL == wrapper) {
216 return false;
217 }
218
219 PLUGIN_PRINTF(("SharedMemory::Init(%p, 0x%08x)\n",
220 static_cast<void*>(plugin),
221 static_cast<unsigned>(length)));
222 // Now allocate the object through the canonical factory and return.
223 allocated_memory = true;
224 }
225
226 if (!DescBasedHandle::Init(plugin, wrapper)) {
227 if (allocated_memory) {
228 wrapper->Delete();
229 }
230 return false;
231 }
232
233 if (0 > wrapper->Map(&addr_, &size_)) {
234 // BUG: we are leaking the shared memory object here.
235 return false;
236 }
237
238 LoadMethods();
239 return true;
240 }
241
242 SharedMemory* SharedMemory::New(Plugin* plugin, nacl::DescWrapper* wrapper) {
243 PLUGIN_PRINTF(("SharedMemory::New()\n"));
244
245 SharedMemory* shared_memory = new(std::nothrow) SharedMemory();
246 if (shared_memory == NULL || !shared_memory->Init(plugin, wrapper, 0)) {
247 return NULL;
248 }
249 return shared_memory;
250 }
251
252 SharedMemory* SharedMemory::New(Plugin* plugin, off_t length) {
253 PLUGIN_PRINTF(("SharedMemory::New()\n"));
254
255 SharedMemory* shared_memory = new(std::nothrow) SharedMemory();
256 if (shared_memory == NULL || !shared_memory->Init(plugin, NULL, length)) {
257 return NULL;
258 }
259 return shared_memory;
260 }
261
262 SharedMemory::SharedMemory() : handle_(0),
263 addr_(NULL),
264 size_(0) {
265 PLUGIN_PRINTF(("SharedMemory::SharedMemory(%p)\n",
266 static_cast<void*>(this)));
267 }
268
269 SharedMemory::~SharedMemory() {
270 PLUGIN_PRINTF(("SharedMemory::~SharedMemory(%p)\n",
271 static_cast<void*>(this)));
272
273 // Invalidates are called by Firefox in abitrary order. Hence, the plugin
274 // could have been freed/trashed before we get invalidated. Therefore, we
275 // cannot use the effp_ member of the plugin object.
276 // TODO(sehr): fix the resulting address space leak.
277 // Free the memory that was mapped to the descriptor.
278 // shared_memory->desc_->vtbl->Unmap(shared_memory->desc_,
279 // shared_memory->plugin_->effp_,
280 // shared_memory->addr_,
281 // shared_memory->size_);
282 // After invalidation, the browser does not respect reference counting,
283 // so we shut down here what we can and prevent attempts to shut down
284 // other linked structures in Deallocate.
285
286 // Free the memory that was mapped to the descriptor.
287 // if (desc() && plugin_) {
288 // desc()->vtbl->Unmap(desc(),
289 // plugin_->effp_,
290 // addr_,
291 // size_);
292 // }
293 // TODO(sehr): is there a missing delete desc() here?
294 // TODO(gregoryd): in addition, should we unref the descriptor if it was
295 // constructed during the initialization of this object?
296 }
297
298 } // namespace plugin
OLDNEW
« no previous file with comments | « src/trusted/plugin/srpc/shared_memory.h ('k') | src/trusted/plugin/srpc/socket_address.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698