| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" | 7 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" |
| 8 | 8 |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include "native_client/src/include/nacl_macros.h" | |
| 11 #include "native_client/src/untrusted/irt/irt.h" | 10 #include "native_client/src/untrusted/irt/irt.h" |
| 12 #include "native_client/src/untrusted/irt/irt_dev.h" | |
| 13 #include "ppapi/nacl_irt/irt_ppapi.h" | 11 #include "ppapi/nacl_irt/irt_ppapi.h" |
| 14 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" | 12 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" |
| 15 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h" | 13 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h" |
| 16 | 14 |
| 17 /* | |
| 18 * This is a whitelist of NaCl IRT interfaces that are exposed under | |
| 19 * PNaCl. This list omits the following: | |
| 20 * | |
| 21 * * The old versions of "irt-memory", v0.1 and v0.2, which contain | |
| 22 * the deprecated sysbrk() function. See: | |
| 23 * https://code.google.com/p/nativeclient/issues/detail?id=3542 | |
| 24 * | |
| 25 * * "irt-mutex", "irt-cond" and "irt-sem", which are deprecated and | |
| 26 * are superseded by the "irt-futex" interface. See: | |
| 27 * https://code.google.com/p/nativeclient/issues/detail?id=3484 | |
| 28 * | |
| 29 * * "irt-dyncode", which is not supported under PNaCl because | |
| 30 * dynamically loading architecture-specific native code is not | |
| 31 * portable. | |
| 32 * | |
| 33 * * "irt-exception-handling", which is not supported under PNaCl | |
| 34 * because it exposes non-portable, architecture-specific register | |
| 35 * state. See: | |
| 36 * https://code.google.com/p/nativeclient/issues/detail?id=3444 | |
| 37 * | |
| 38 * * "irt-blockhook", which is deprecated. It was provided for | |
| 39 * implementing thread suspension for conservative garbage | |
| 40 * collection, but this is probably not a portable use case under | |
| 41 * PNaCl, so this interface is disabled under PNaCl. See: | |
| 42 * https://code.google.com/p/nativeclient/issues/detail?id=3539 | |
| 43 * | |
| 44 * * "irt-resource-open". This was primarily provided for use by | |
| 45 * nacl-glibc's dynamic linker, which is not supported under PNaCl. | |
| 46 * open_resource() returns a file descriptor, but it is the only | |
| 47 * interface in NaCl to do so inside Chromium. This is | |
| 48 * inconsistent with PPAPI, which does not expose file descriptors | |
| 49 * (except in private/dev interfaces). See: | |
| 50 * https://code.google.com/p/nativeclient/issues/detail?id=3574 | |
| 51 * | |
| 52 * * "irt-fdio" and "irt-filename". Under PNaCl, where | |
| 53 * open_resource() open is disallowed, these are only useful for | |
| 54 * debugging. They are only allowed via the "dev" query strings; | |
| 55 * the non-"dev" query strings are disallowed. | |
| 56 * | |
| 57 * We omit these because they are only "dev" interfaces: | |
| 58 * | |
| 59 * * "irt-dev-getpid" | |
| 60 * * "irt-dev-list-mappings" | |
| 61 */ | |
| 62 static const char *const irt_interface_whitelist[] = { | |
| 63 NACL_IRT_BASIC_v0_1, | |
| 64 NACL_IRT_MEMORY_v0_3, | |
| 65 NACL_IRT_THREAD_v0_1, | |
| 66 NACL_IRT_FUTEX_v0_1, | |
| 67 NACL_IRT_TLS_v0_1, | |
| 68 NACL_IRT_PPAPIHOOK_v0_1, | |
| 69 NACL_IRT_RANDOM_v0_1, | |
| 70 NACL_IRT_CLOCK_v0_1, | |
| 71 /* Allowed for debugging purposes: */ | |
| 72 NACL_IRT_DEV_FDIO_v0_1, | |
| 73 NACL_IRT_DEV_FILENAME_v0_2, | |
| 74 }; | |
| 75 | |
| 76 /* Use local strcmp to avoid dependency on libc. */ | 15 /* Use local strcmp to avoid dependency on libc. */ |
| 77 static int mystrcmp(const char* s1, const char *s2) { | 16 static int mystrcmp(const char* s1, const char *s2) { |
| 78 while((*s1 && *s2) && (*s1++ == *s2++)); | 17 while((*s1 && *s2) && (*s1++ == *s2++)); |
| 79 return *(--s1) - *(--s2); | 18 return *(--s1) - *(--s2); |
| 80 } | 19 } |
| 81 | 20 |
| 82 static int is_irt_interface_whitelisted(const char *interface_name) { | |
| 83 int i; | |
| 84 for (i = 0; i < NACL_ARRAY_SIZE(irt_interface_whitelist); i++) { | |
| 85 if (mystrcmp(interface_name, irt_interface_whitelist[i]) == 0) { | |
| 86 return 1; | |
| 87 } | |
| 88 } | |
| 89 return 0; | |
| 90 } | |
| 91 | |
| 92 TYPE_nacl_irt_query __pnacl_real_irt_interface = NULL; | 21 TYPE_nacl_irt_query __pnacl_real_irt_interface = NULL; |
| 93 | 22 |
| 94 /* | 23 /* |
| 95 * These remember the interface pointers the user registers by calling the | 24 * These remember the interface pointers the user registers by calling the |
| 96 * IRT entry point. | 25 * IRT entry point. |
| 97 */ | 26 */ |
| 98 static struct PP_StartFunctions user_start_functions; | 27 static struct PP_StartFunctions user_start_functions; |
| 99 | 28 |
| 100 static int32_t wrap_PPPInitializeModule(PP_Module module_id, | 29 static int32_t wrap_PPPInitializeModule(PP_Module module_id, |
| 101 PPB_GetInterface get_browser_intf) { | 30 PPB_GetInterface get_browser_intf) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 132 __set_real_Pnacl_PPPGetInterface(user_start_functions.PPP_GetInterface); | 61 __set_real_Pnacl_PPPGetInterface(user_start_functions.PPP_GetInterface); |
| 133 | 62 |
| 134 /* | 63 /* |
| 135 * Invoke the IRT's ppapi_start interface with the wrapped interface. | 64 * Invoke the IRT's ppapi_start interface with the wrapped interface. |
| 136 */ | 65 */ |
| 137 return (*real_irt_ppapi_hook.ppapi_start)(&wrapped_ppapi_methods); | 66 return (*real_irt_ppapi_hook.ppapi_start)(&wrapped_ppapi_methods); |
| 138 } | 67 } |
| 139 | 68 |
| 140 size_t __pnacl_irt_interface_wrapper(const char *interface_ident, | 69 size_t __pnacl_irt_interface_wrapper(const char *interface_ident, |
| 141 void *table, size_t tablesize) { | 70 void *table, size_t tablesize) { |
| 142 if (!is_irt_interface_whitelisted(interface_ident)) | |
| 143 return 0; | |
| 144 | |
| 145 /* | 71 /* |
| 146 * Note there is a benign race in initializing the wrapper. | 72 * Note there is a benign race in initializing the wrapper. |
| 147 * We build the "hook" structure by copying from the IRT's hook and then | 73 * We build the "hook" structure by copying from the IRT's hook and then |
| 148 * writing our wrapper for the ppapi method. Two threads may end up | 74 * writing our wrapper for the ppapi method. Two threads may end up |
| 149 * attempting to do this simultaneously, which should not be a problem, | 75 * attempting to do this simultaneously, which should not be a problem, |
| 150 * as they are writing the same values. | 76 * as they are writing the same values. |
| 151 */ | 77 */ |
| 152 if (0 != mystrcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { | 78 if (0 != mystrcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { |
| 153 /* | 79 /* |
| 154 * The interface is not wrapped, so use the real interface. | 80 * The interface is not wrapped, so use the real interface. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 166 */ | 92 */ |
| 167 struct nacl_irt_ppapihook *dest = table; | 93 struct nacl_irt_ppapihook *dest = table; |
| 168 if (sizeof *dest <= tablesize) { | 94 if (sizeof *dest <= tablesize) { |
| 169 dest->ppapi_start = wrap_ppapi_start; | 95 dest->ppapi_start = wrap_ppapi_start; |
| 170 dest->ppapi_register_thread_creator = | 96 dest->ppapi_register_thread_creator = |
| 171 real_irt_ppapi_hook.ppapi_register_thread_creator; | 97 real_irt_ppapi_hook.ppapi_register_thread_creator; |
| 172 return sizeof *dest; | 98 return sizeof *dest; |
| 173 } | 99 } |
| 174 return 0; | 100 return 0; |
| 175 } | 101 } |
| OLD | NEW |