Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / desc_cacheability / desc_cacheability.c
1 /*
2  * Copyright (c) 2013 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 "native_client/src/trusted/desc_cacheability/desc_cacheability.h"
8
9 #include "native_client/src/include/portability.h"
10 #include "native_client/src/public/desc_metadata_types.h"
11 #include "native_client/src/shared/platform/nacl_log.h"
12 #include "native_client/src/trusted/desc/nacl_desc_base.h"
13 #include "native_client/src/trusted/desc/nacl_desc_io.h"
14 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
15 #include "native_client/src/trusted/validator/nacl_file_info.h"
16 #include "native_client/src/trusted/validator/rich_file_info.h"
17 #include "native_client/src/trusted/validator/validation_cache.h"
18
19 int NaClDescSetFileToken(struct NaClDesc *desc,
20                          struct NaClFileToken const *token) {
21   int error;
22   error = (*NACL_VTBL(NaClDesc, desc)->
23            SetMetadata)(desc,
24                         NACL_DESC_METADATA_FILE_TOKEN_TYPE,
25                         sizeof *token, (uint8_t const *) token);
26   if (0 != error) {
27     NaClLog(4, "NaClDescSetFileToken: failed, errno %d\n", -error);
28     return 0;
29   }
30   return 1;
31 }
32
33 int NaClDescGetFileToken(struct NaClDesc *desc,
34                          struct NaClFileToken *out_token) {
35   int32_t metadata_type;
36   uint32_t metadata_bytes;
37
38   metadata_bytes = (uint32_t) sizeof *out_token;
39   metadata_type = (*NACL_VTBL(NaClDesc, desc)->
40                    GetMetadata)(desc, &metadata_bytes,
41                                 (uint8_t *) out_token);
42   if (NACL_DESC_METADATA_NONE_TYPE == metadata_type) {
43     NaClLog(4, "NaClDescGetFileToken: no meta data, cannot map\n");
44     return 0;
45   } else if (NACL_DESC_METADATA_FILE_TOKEN_TYPE != metadata_type) {
46     return 0;
47   } else if (metadata_bytes != (uint32_t) sizeof *out_token) {
48     /* there is supposed to be a file token, but wrong size? */
49     NaClLog(LOG_WARNING,
50             "NaClDescGetFileToken: purported file token present,"
51             " but token size is incorrect.\n");
52     return 0;
53   }
54   NaClLog(4,
55           "NaClDescGetFileToken: got token 0x%"NACL_PRIx64":%"NACL_PRIx64"\n",
56           out_token->hi, out_token->lo);
57   return 1;
58 }
59
60 struct NaClDesc *NaClExchangeFileTokenForMappableDesc(
61     struct NaClFileToken *file_token,
62     struct NaClValidationCache *validation_cache) {
63   int32_t new_fd;
64   char *file_path;
65   uint32_t file_path_length;
66   struct NaClDesc *desc = NULL;
67
68   /*
69    * Not all file loading paths will produce a valid token.  Zero is
70    * an invalid token value that indicates there is nothing to
71    * resolve.  In this case, assume nothing about the providence of
72    * the file.
73    */
74   if (!(file_token->lo == 0 && file_token->hi == 0) &&
75       validation_cache->ResolveFileToken != NULL &&
76       validation_cache->ResolveFileToken(validation_cache->handle,
77                                          file_token,
78                                          &new_fd,
79                                          &file_path,
80                                          &file_path_length)) {
81     struct NaClRichFileInfo info;
82
83     desc = NaClDescIoDescFromHandleAllocCtor((NaClHandle) new_fd,
84                                              NACL_ABI_O_RDONLY);
85
86     /* Mark the desc as OK for mmapping. */
87     NaClDescMarkSafeForMmap(desc);
88
89     /* Provide metadata for validation. */
90     NaClRichFileInfoCtor(&info);
91     info.known_file = 1;
92     info.file_path = file_path;  /* Takes ownership. */
93     info.file_path_length = file_path_length;
94     NaClSetFileOriginInfo(desc, &info);
95     NaClRichFileInfoDtor(&info);
96   }
97   return desc;
98 }
99
100 void NaClReplaceDescIfValidationCacheAssertsMappable(
101     struct NaClDesc **desc_in_out,
102     struct NaClValidationCache *validation_cache) {
103   struct NaClDesc *desc = *desc_in_out;
104   struct NaClDesc *replacement;
105   struct NaClFileToken file_token;
106
107   if (!NaClDescGetFileToken(desc, &file_token)) {
108     NaClLog(4,
109             "NaClReplaceDescIfValidationCacheAssertsMappable: no valid"
110             " file token\n");
111   } else {
112     replacement = NaClExchangeFileTokenForMappableDesc(&file_token,
113                                                        validation_cache);
114     if (NULL != replacement) {
115       NaClDescUnref(desc);
116       *desc_in_out = replacement;
117     }
118   }
119 }