OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. |
| 5 */ |
| 6 |
| 7 #include <string.h> |
| 8 |
| 9 #include "native_client/src/trusted/service_runtime/nacl_resource.h" |
| 10 |
| 11 #include "native_client/src/include/nacl_base.h" |
| 12 #include "native_client/src/include/nacl_macros.h" |
| 13 #include "native_client/src/shared/platform/nacl_check.h" |
| 14 #include "native_client/src/shared/platform/nacl_log.h" |
| 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" |
| 16 #include "native_client/src/trusted/desc/nacl_desc_io.h" |
| 17 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" |
| 18 #include "native_client/src/trusted/service_runtime/nacl_desc_postmessage.h" |
| 19 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
| 20 |
| 21 struct NaClDesc *NaClResourceOpen(struct NaClResource *self, |
| 22 char const *resource_locator, |
| 23 int nacl_flags, |
| 24 int mode) { |
| 25 size_t ix; |
| 26 size_t default_ix = ~(size_t) 0; /* greater than self->num_schemes */ |
| 27 size_t prefix_len; |
| 28 int allow_debug = 0; |
| 29 |
| 30 NaClLog(4, "NaClResourceOpen(*,\"%s\",0x%x,0x%x)\n", |
| 31 resource_locator, nacl_flags, mode); |
| 32 prefix_len = strlen(NACL_RESOURCE_DEBUG_WARNING); |
| 33 if (strncmp(resource_locator, NACL_RESOURCE_DEBUG_WARNING, |
| 34 prefix_len) == 0) { |
| 35 allow_debug = 1; |
| 36 resource_locator += prefix_len; |
| 37 } |
| 38 |
| 39 for (ix = 0; ix < self->num_schemes; ++ix) { |
| 40 if (self->schemes[ix].default_scheme) { |
| 41 default_ix = ix; |
| 42 } |
| 43 prefix_len = strlen(self->schemes[ix].scheme_prefix); |
| 44 NaClLog(4, " prefix \"%s\"\n", self->schemes[ix].scheme_prefix); |
| 45 if (0 == strncmp(self->schemes[ix].scheme_prefix, resource_locator, |
| 46 prefix_len)) { |
| 47 char const *rest = resource_locator + prefix_len; |
| 48 NaClLog(4, " prefix match at %"NACL_PRIuS", rest \"%s\".\n", ix, rest); |
| 49 return (*self->schemes[ix].Open)(self, rest, |
| 50 nacl_flags, mode, allow_debug); |
| 51 } |
| 52 } |
| 53 if (default_ix < self->num_schemes) { |
| 54 NaClLog(4, " trying default scheme %"NACL_PRIuS".\n", default_ix); |
| 55 return (*self->schemes[default_ix].Open)(self, resource_locator, |
| 56 nacl_flags, mode, allow_debug); |
| 57 } |
| 58 return NULL; |
| 59 } |
| 60 |
| 61 int NaClResourceCtor(struct NaClResource *self, |
| 62 struct NaClResourceSchemes const *scheme_tbl, |
| 63 size_t num_schemes) { |
| 64 self->schemes = scheme_tbl; |
| 65 self->num_schemes = num_schemes; |
| 66 return 1; |
| 67 } |
| 68 |
| 69 /* -------------------------------------------------------------------------- |
| 70 * |
| 71 * Subclass of NaClResource |
| 72 * |
| 73 * -------------------------------------------------------------------------- |
| 74 */ |
| 75 |
| 76 int NaClResourceNaClAppCtor(struct NaClResourceNaClApp *self, |
| 77 struct NaClResourceSchemes const *scheme_tbl, |
| 78 size_t num_schemes, |
| 79 struct NaClApp *nap) { |
| 80 NaClLog(4, |
| 81 ("NaClResourceNaClAppCtor, scheme_tbl 0x%"NACL_PRIxPTR"," |
| 82 " size %"NACL_PRIuS".\n"), |
| 83 (uintptr_t) scheme_tbl, num_schemes); |
| 84 if (!NaClResourceCtor(&self->base, scheme_tbl, num_schemes)) { |
| 85 return 0; |
| 86 } |
| 87 self->nap = nap; |
| 88 return 1; |
| 89 } |
| 90 |
| 91 static struct NaClDesc *NaClResourceNaClAppFileOpen( |
| 92 struct NaClResource *vself, |
| 93 char const *resource_locator, |
| 94 int nacl_flags, |
| 95 int mode, |
| 96 int allow_debug) { |
| 97 struct NaClResourceNaClApp *self = (struct NaClResourceNaClApp *) vself; |
| 98 struct NaClHostDesc *hd = NULL; |
| 99 struct NaClDescIoDesc *did = NULL; |
| 100 struct NaClDesc *rv = NULL; |
| 101 |
| 102 /* |
| 103 * Functionality-wise, we're startup phase-independent; we can |
| 104 * always try to open a file; however, initialization requires that |
| 105 * file opens occur only early, in NACl_RESOURCE_PHASE_START. |
| 106 */ |
| 107 UNREFERENCED_PARAMETER(allow_debug); |
| 108 if (self->nap->resource_phase != NACL_RESOURCE_PHASE_START) { |
| 109 return NULL; |
| 110 } |
| 111 hd = malloc(sizeof *hd); |
| 112 did = malloc(sizeof *did); |
| 113 if (NULL == hd || NULL == did) { |
| 114 goto done; |
| 115 } |
| 116 if (!NaClHostDescOpen(hd, resource_locator, nacl_flags, mode)) { |
| 117 goto done; |
| 118 } |
| 119 if (!NaClDescIoDescCtor(did, hd)) { |
| 120 (void) NaClHostDescClose(hd); |
| 121 goto done; |
| 122 } |
| 123 hd = NULL; /* ownership passed into did */ |
| 124 rv = (struct NaClDesc *) did; /* success */ |
| 125 did = NULL; |
| 126 done: |
| 127 free(hd); |
| 128 free(did); |
| 129 return rv; |
| 130 } |
| 131 |
| 132 /* |
| 133 * We don't bother to make it a singleton postmessage device. Thread |
| 134 * safety is handled when the device object gets the lock to use the |
| 135 * reverse channel. |
| 136 */ |
| 137 static struct NaClDesc *NaClResourceNaClAppDevOpen( |
| 138 struct NaClResource *vself, |
| 139 char const *resource_locator, |
| 140 int nacl_flags, |
| 141 int mode, |
| 142 int allow_debug) { |
| 143 struct NaClResourceNaClApp *self = (struct NaClResourceNaClApp *) vself; |
| 144 struct NaClDescPostMessage *ndpm = NULL; |
| 145 |
| 146 if (self->nap->resource_phase != NACL_RESOURCE_PHASE_REV_CHAN |
| 147 || !allow_debug) { |
| 148 return NULL; |
| 149 } |
| 150 |
| 151 if (0 == strcmp(resource_locator, NACL_RESOURCE_DEV_POSTMESSAGE_LOCATOR)) { |
| 152 /* disallow O_RDONLY or O_RDWR */ |
| 153 if ((NACL_ABI_O_ACCMODE & nacl_flags) != NACL_ABI_O_WRONLY) { |
| 154 return NULL; |
| 155 } |
| 156 /* allow O_CREAT, O_APPEND, and O_TRUNC */ |
| 157 UNREFERENCED_PARAMETER(mode); /* ignored; O_CREAT doesn't create. */ |
| 158 |
| 159 ndpm = malloc(sizeof *ndpm); |
| 160 CHECK(NULL != ndpm); |
| 161 CHECK(NaClDescPostMessageCtor(ndpm, self->nap)); |
| 162 } |
| 163 return (struct NaClDesc *) ndpm; |
| 164 } |
| 165 |
| 166 int NaClResourceNaClAppInit(struct NaClResourceNaClApp *rp, |
| 167 struct NaClApp *nap) { |
| 168 static struct NaClResourceSchemes const schemes[] = { |
| 169 { |
| 170 NACL_RESOURCE_FILE_PREFIX, |
| 171 1, /* default scheme */ |
| 172 NaClResourceNaClAppFileOpen, |
| 173 }, { |
| 174 NACL_RESOURCE_DEV_PREFIX, |
| 175 0, /* not default scheme */ |
| 176 NaClResourceNaClAppDevOpen, |
| 177 }, |
| 178 }; |
| 179 |
| 180 NaClLog(4, "NaClResourceNaClAppInit -- Ctor with default schemes\n"); |
| 181 return NaClResourceNaClAppCtor(rp, schemes, NACL_ARRAY_SIZE(schemes), nap); |
| 182 } |
OLD | NEW |