xref: /aosp_15_r20/trusty/kernel/lib/app_manifest/app_manifest.c (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (c) 2021 Google Inc. All rights reserved
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker  * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker  * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker  * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker  * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker  * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker  * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker  *
12*344aa361SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker  * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker  *
15*344aa361SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker  */
23*344aa361SAndroid Build Coastguard Worker 
24*344aa361SAndroid Build Coastguard Worker #define TLOG_TAG "app_manifest"
25*344aa361SAndroid Build Coastguard Worker 
26*344aa361SAndroid Build Coastguard Worker #include <assert.h>
27*344aa361SAndroid Build Coastguard Worker #include <inttypes.h>
28*344aa361SAndroid Build Coastguard Worker #include <lib/app_manifest/app_manifest.h>
29*344aa361SAndroid Build Coastguard Worker #include <lk/macros.h>
30*344aa361SAndroid Build Coastguard Worker #include <string.h>
31*344aa361SAndroid Build Coastguard Worker #include <trusty_log.h>
32*344aa361SAndroid Build Coastguard Worker #include <uapi/err.h>
33*344aa361SAndroid Build Coastguard Worker 
app_manifest_iterator_reset(struct app_manifest_iterator * iterator,const char * manifest_data,size_t manifest_size)34*344aa361SAndroid Build Coastguard Worker int app_manifest_iterator_reset(struct app_manifest_iterator* iterator,
35*344aa361SAndroid Build Coastguard Worker                                 const char* manifest_data,
36*344aa361SAndroid Build Coastguard Worker                                 size_t manifest_size) {
37*344aa361SAndroid Build Coastguard Worker     assert(iterator);
38*344aa361SAndroid Build Coastguard Worker 
39*344aa361SAndroid Build Coastguard Worker     iterator->manifest_data = manifest_data;
40*344aa361SAndroid Build Coastguard Worker     iterator->manifest_size = manifest_size;
41*344aa361SAndroid Build Coastguard Worker     iterator->index = 0;
42*344aa361SAndroid Build Coastguard Worker     iterator->app_name = "<unknown>";
43*344aa361SAndroid Build Coastguard Worker     iterator->error = NO_ERROR;
44*344aa361SAndroid Build Coastguard Worker 
45*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
46*344aa361SAndroid Build Coastguard Worker }
47*344aa361SAndroid Build Coastguard Worker 
48*344aa361SAndroid Build Coastguard Worker /*
49*344aa361SAndroid Build Coastguard Worker  * Helper function that gets the pointer to the next object in the manifest
50*344aa361SAndroid Build Coastguard Worker  * after checking that the object does not extend past the end of the manifest
51*344aa361SAndroid Build Coastguard Worker  */
app_manifest_get_ptr(struct app_manifest_iterator * iterator,size_t size)52*344aa361SAndroid Build Coastguard Worker static inline const void* app_manifest_get_ptr(
53*344aa361SAndroid Build Coastguard Worker         struct app_manifest_iterator* iterator,
54*344aa361SAndroid Build Coastguard Worker         size_t size) {
55*344aa361SAndroid Build Coastguard Worker     const void* curr = &iterator->manifest_data[iterator->index];
56*344aa361SAndroid Build Coastguard Worker     if (size > iterator->manifest_size - iterator->index) {
57*344aa361SAndroid Build Coastguard Worker         iterator->error = ERR_NOT_VALID;
58*344aa361SAndroid Build Coastguard Worker         return NULL;
59*344aa361SAndroid Build Coastguard Worker     }
60*344aa361SAndroid Build Coastguard Worker     iterator->index += size;
61*344aa361SAndroid Build Coastguard Worker     return curr;
62*344aa361SAndroid Build Coastguard Worker }
63*344aa361SAndroid Build Coastguard Worker 
64*344aa361SAndroid Build Coastguard Worker /*
65*344aa361SAndroid Build Coastguard Worker  * Helper function that reads a sized object from the manifest after
66*344aa361SAndroid Build Coastguard Worker  * checking that the object does not extend past the end of the manifest
67*344aa361SAndroid Build Coastguard Worker  */
app_manifest_read_ptr(struct app_manifest_iterator * iterator,void * dest,size_t size)68*344aa361SAndroid Build Coastguard Worker static inline void app_manifest_read_ptr(struct app_manifest_iterator* iterator,
69*344aa361SAndroid Build Coastguard Worker                                          void* dest,
70*344aa361SAndroid Build Coastguard Worker                                          size_t size) {
71*344aa361SAndroid Build Coastguard Worker     const void* src = app_manifest_get_ptr(iterator, size);
72*344aa361SAndroid Build Coastguard Worker     if (src) {
73*344aa361SAndroid Build Coastguard Worker         memcpy(dest, src, size);
74*344aa361SAndroid Build Coastguard Worker     }
75*344aa361SAndroid Build Coastguard Worker }
76*344aa361SAndroid Build Coastguard Worker 
77*344aa361SAndroid Build Coastguard Worker /* Helper function that reads one entry and advances the iterator */
app_manifest_read_entry(struct app_manifest_iterator * iterator)78*344aa361SAndroid Build Coastguard Worker static inline uint32_t app_manifest_read_entry(
79*344aa361SAndroid Build Coastguard Worker         struct app_manifest_iterator* iterator) {
80*344aa361SAndroid Build Coastguard Worker     uint32_t entry = 0;
81*344aa361SAndroid Build Coastguard Worker     app_manifest_read_ptr(iterator, &entry, sizeof(entry));
82*344aa361SAndroid Build Coastguard Worker     return entry;
83*344aa361SAndroid Build Coastguard Worker }
84*344aa361SAndroid Build Coastguard Worker 
app_manifest_read_string(struct app_manifest_iterator * iterator,uint32_t string_size,const char * string_name)85*344aa361SAndroid Build Coastguard Worker static inline const char* app_manifest_read_string(
86*344aa361SAndroid Build Coastguard Worker         struct app_manifest_iterator* iterator,
87*344aa361SAndroid Build Coastguard Worker         uint32_t string_size,
88*344aa361SAndroid Build Coastguard Worker         const char* string_name) {
89*344aa361SAndroid Build Coastguard Worker     uint32_t string_entries;
90*344aa361SAndroid Build Coastguard Worker     size_t string_length;
91*344aa361SAndroid Build Coastguard Worker     const char* string;
92*344aa361SAndroid Build Coastguard Worker 
93*344aa361SAndroid Build Coastguard Worker     /* string size with padding */
94*344aa361SAndroid Build Coastguard Worker     string_entries = round_up(string_size, sizeof(uint32_t));
95*344aa361SAndroid Build Coastguard Worker     if (string_entries == 0) {
96*344aa361SAndroid Build Coastguard Worker         TLOGE("invalid %s-size 0x%" PRIx32 "/0x%" PRIx32 "\n", string_name,
97*344aa361SAndroid Build Coastguard Worker               string_size, string_entries);
98*344aa361SAndroid Build Coastguard Worker         return NULL;
99*344aa361SAndroid Build Coastguard Worker     }
100*344aa361SAndroid Build Coastguard Worker 
101*344aa361SAndroid Build Coastguard Worker     string = app_manifest_get_ptr(iterator, string_entries);
102*344aa361SAndroid Build Coastguard Worker     if (!string) {
103*344aa361SAndroid Build Coastguard Worker         TLOGE("manifest too small %zu, missing %s, "
104*344aa361SAndroid Build Coastguard Worker               "%s-size 0x%" PRIx32 "/0x%" PRIx32 "\n",
105*344aa361SAndroid Build Coastguard Worker               iterator->manifest_size, string_name, string_name, string_size,
106*344aa361SAndroid Build Coastguard Worker               string_entries);
107*344aa361SAndroid Build Coastguard Worker         return NULL;
108*344aa361SAndroid Build Coastguard Worker     }
109*344aa361SAndroid Build Coastguard Worker 
110*344aa361SAndroid Build Coastguard Worker     /*
111*344aa361SAndroid Build Coastguard Worker      * Make sure that the string has exactly one \0 and it's the last character
112*344aa361SAndroid Build Coastguard Worker      */
113*344aa361SAndroid Build Coastguard Worker     string_length = strnlen(string, string_size);
114*344aa361SAndroid Build Coastguard Worker     if (string_length != string_size - 1) {
115*344aa361SAndroid Build Coastguard Worker         TLOGE("%s-length invalid 0x%zx, %s-size 0x%" PRIx32 "/0x%" PRIx32 "\n",
116*344aa361SAndroid Build Coastguard Worker               string_name, string_length, string_name, string_size,
117*344aa361SAndroid Build Coastguard Worker               string_entries);
118*344aa361SAndroid Build Coastguard Worker         return NULL;
119*344aa361SAndroid Build Coastguard Worker     }
120*344aa361SAndroid Build Coastguard Worker 
121*344aa361SAndroid Build Coastguard Worker     return string;
122*344aa361SAndroid Build Coastguard Worker }
123*344aa361SAndroid Build Coastguard Worker 
app_manifest_iterator_next(struct app_manifest_iterator * iterator,struct app_manifest_config_entry * entry,int * out_error)124*344aa361SAndroid Build Coastguard Worker bool app_manifest_iterator_next(struct app_manifest_iterator* iterator,
125*344aa361SAndroid Build Coastguard Worker                                 struct app_manifest_config_entry* entry,
126*344aa361SAndroid Build Coastguard Worker                                 int* out_error) {
127*344aa361SAndroid Build Coastguard Worker     assert(entry);
128*344aa361SAndroid Build Coastguard Worker 
129*344aa361SAndroid Build Coastguard Worker     if (iterator->index >= iterator->manifest_size) {
130*344aa361SAndroid Build Coastguard Worker         if (out_error) {
131*344aa361SAndroid Build Coastguard Worker             *out_error = NO_ERROR;
132*344aa361SAndroid Build Coastguard Worker         }
133*344aa361SAndroid Build Coastguard Worker         return false;
134*344aa361SAndroid Build Coastguard Worker     }
135*344aa361SAndroid Build Coastguard Worker 
136*344aa361SAndroid Build Coastguard Worker     /*
137*344aa361SAndroid Build Coastguard Worker      * uuid and app_name are special cases: we return them
138*344aa361SAndroid Build Coastguard Worker      * using pseudo-keys because they're not present in the entries
139*344aa361SAndroid Build Coastguard Worker      */
140*344aa361SAndroid Build Coastguard Worker     uint32_t manifest_key;
141*344aa361SAndroid Build Coastguard Worker     if (iterator->index == 0) {
142*344aa361SAndroid Build Coastguard Worker         manifest_key = APP_MANIFEST_CONFIG_KEY_UUID;
143*344aa361SAndroid Build Coastguard Worker     } else if (iterator->index == sizeof(uuid_t)) {
144*344aa361SAndroid Build Coastguard Worker         manifest_key = APP_MANIFEST_CONFIG_KEY_APP_NAME;
145*344aa361SAndroid Build Coastguard Worker     } else {
146*344aa361SAndroid Build Coastguard Worker         manifest_key = app_manifest_read_entry(iterator);
147*344aa361SAndroid Build Coastguard Worker     }
148*344aa361SAndroid Build Coastguard Worker 
149*344aa361SAndroid Build Coastguard Worker     uint32_t string_size;
150*344aa361SAndroid Build Coastguard Worker     const char* string;
151*344aa361SAndroid Build Coastguard Worker     switch (manifest_key) {
152*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MIN_STACK_SIZE:
153*344aa361SAndroid Build Coastguard Worker         entry->value.min_stack_size = app_manifest_read_entry(iterator);
154*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
155*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MIN_STACK_SIZE value of app %s\n",
156*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
157*344aa361SAndroid Build Coastguard Worker             goto error;
158*344aa361SAndroid Build Coastguard Worker         }
159*344aa361SAndroid Build Coastguard Worker         break;
160*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MIN_SHADOW_STACK_SIZE:
161*344aa361SAndroid Build Coastguard Worker         entry->value.min_shadow_stack_size = app_manifest_read_entry(iterator);
162*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
163*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MIN_SHADOW_STACK_SIZE value of app %s\n",
164*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
165*344aa361SAndroid Build Coastguard Worker             goto error;
166*344aa361SAndroid Build Coastguard Worker         }
167*344aa361SAndroid Build Coastguard Worker         break;
168*344aa361SAndroid Build Coastguard Worker 
169*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MIN_HEAP_SIZE:
170*344aa361SAndroid Build Coastguard Worker         entry->value.min_heap_size = app_manifest_read_entry(iterator);
171*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
172*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MIN_HEAP_SIZE value of app %s\n",
173*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
174*344aa361SAndroid Build Coastguard Worker             goto error;
175*344aa361SAndroid Build Coastguard Worker         }
176*344aa361SAndroid Build Coastguard Worker         break;
177*344aa361SAndroid Build Coastguard Worker 
178*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MAP_MEM:
179*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.id = app_manifest_read_entry(iterator);
180*344aa361SAndroid Build Coastguard Worker         /*
181*344aa361SAndroid Build Coastguard Worker          * TODO: add big endian support? The manifest_compiler wrote the
182*344aa361SAndroid Build Coastguard Worker          * next two entries as 64 bit numbers with the byte order of the
183*344aa361SAndroid Build Coastguard Worker          * build machine. The code below assumes the manifest data and
184*344aa361SAndroid Build Coastguard Worker          * device are both little-endian.
185*344aa361SAndroid Build Coastguard Worker          */
186*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.offset = app_manifest_read_entry(iterator);
187*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.offset |=
188*344aa361SAndroid Build Coastguard Worker                 (uint64_t)app_manifest_read_entry(iterator) << 32;
189*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.size = app_manifest_read_entry(iterator);
190*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.size |= (uint64_t)app_manifest_read_entry(iterator)
191*344aa361SAndroid Build Coastguard Worker                                      << 32;
192*344aa361SAndroid Build Coastguard Worker         entry->value.mem_map.arch_mmu_flags = app_manifest_read_entry(iterator);
193*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
194*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MAP_MEM value of app %s\n",
195*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
196*344aa361SAndroid Build Coastguard Worker             goto error;
197*344aa361SAndroid Build Coastguard Worker         }
198*344aa361SAndroid Build Coastguard Worker         break;
199*344aa361SAndroid Build Coastguard Worker 
200*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MGMT_FLAGS:
201*344aa361SAndroid Build Coastguard Worker         entry->value.mgmt_flags = app_manifest_read_entry(iterator);
202*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
203*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MGMT_FLAGS value of app %s\n",
204*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
205*344aa361SAndroid Build Coastguard Worker             goto error;
206*344aa361SAndroid Build Coastguard Worker         }
207*344aa361SAndroid Build Coastguard Worker         break;
208*344aa361SAndroid Build Coastguard Worker 
209*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_START_PORT:
210*344aa361SAndroid Build Coastguard Worker         entry->value.start_port.flags = app_manifest_read_entry(iterator);
211*344aa361SAndroid Build Coastguard Worker 
212*344aa361SAndroid Build Coastguard Worker         string_size = app_manifest_read_entry(iterator);
213*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
214*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing START_PORT values of app %s\n",
215*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
216*344aa361SAndroid Build Coastguard Worker             goto error;
217*344aa361SAndroid Build Coastguard Worker         }
218*344aa361SAndroid Build Coastguard Worker 
219*344aa361SAndroid Build Coastguard Worker         string = app_manifest_read_string(iterator, string_size,
220*344aa361SAndroid Build Coastguard Worker                                           "start-port-name");
221*344aa361SAndroid Build Coastguard Worker         if (!string) {
222*344aa361SAndroid Build Coastguard Worker             goto error;
223*344aa361SAndroid Build Coastguard Worker         }
224*344aa361SAndroid Build Coastguard Worker 
225*344aa361SAndroid Build Coastguard Worker         entry->value.start_port.name_size = string_size;
226*344aa361SAndroid Build Coastguard Worker         entry->value.start_port.name = string;
227*344aa361SAndroid Build Coastguard Worker         break;
228*344aa361SAndroid Build Coastguard Worker 
229*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_PINNED_CPU:
230*344aa361SAndroid Build Coastguard Worker         entry->value.pinned_cpu = (int)app_manifest_read_entry(iterator);
231*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
232*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing PINNED_CPU value of app %s\n",
233*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
234*344aa361SAndroid Build Coastguard Worker             goto error;
235*344aa361SAndroid Build Coastguard Worker         }
236*344aa361SAndroid Build Coastguard Worker         break;
237*344aa361SAndroid Build Coastguard Worker 
238*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_PRIORITY:
239*344aa361SAndroid Build Coastguard Worker         entry->value.priority = (int)app_manifest_read_entry(iterator);
240*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
241*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing PRIORITY value of app %s\n",
242*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
243*344aa361SAndroid Build Coastguard Worker             goto error;
244*344aa361SAndroid Build Coastguard Worker         }
245*344aa361SAndroid Build Coastguard Worker         break;
246*344aa361SAndroid Build Coastguard Worker 
247*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_VERSION:
248*344aa361SAndroid Build Coastguard Worker         entry->value.version = app_manifest_read_entry(iterator);
249*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
250*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing VERSION value of app %s\n",
251*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
252*344aa361SAndroid Build Coastguard Worker             goto error;
253*344aa361SAndroid Build Coastguard Worker         }
254*344aa361SAndroid Build Coastguard Worker         break;
255*344aa361SAndroid Build Coastguard Worker 
256*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_MIN_VERSION:
257*344aa361SAndroid Build Coastguard Worker         entry->value.min_version = app_manifest_read_entry(iterator);
258*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
259*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing MIN_VERSION value of app %s\n",
260*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
261*344aa361SAndroid Build Coastguard Worker             goto error;
262*344aa361SAndroid Build Coastguard Worker         }
263*344aa361SAndroid Build Coastguard Worker         break;
264*344aa361SAndroid Build Coastguard Worker 
265*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_APPLOADER_FLAGS:
266*344aa361SAndroid Build Coastguard Worker         entry->value.apploader_flags = app_manifest_read_entry(iterator);
267*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
268*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest missing APPLOADER_FLAGS value of app %s\n",
269*344aa361SAndroid Build Coastguard Worker                   iterator->app_name);
270*344aa361SAndroid Build Coastguard Worker             goto error;
271*344aa361SAndroid Build Coastguard Worker         }
272*344aa361SAndroid Build Coastguard Worker         break;
273*344aa361SAndroid Build Coastguard Worker 
274*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_UUID:
275*344aa361SAndroid Build Coastguard Worker         app_manifest_read_ptr(iterator, &entry->value.uuid,
276*344aa361SAndroid Build Coastguard Worker                               sizeof(entry->value.uuid));
277*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
278*344aa361SAndroid Build Coastguard Worker             TLOGE("manifest too small %zu, missing uuid\n",
279*344aa361SAndroid Build Coastguard Worker                   iterator->manifest_size);
280*344aa361SAndroid Build Coastguard Worker             goto error;
281*344aa361SAndroid Build Coastguard Worker         }
282*344aa361SAndroid Build Coastguard Worker         break;
283*344aa361SAndroid Build Coastguard Worker 
284*344aa361SAndroid Build Coastguard Worker     case APP_MANIFEST_CONFIG_KEY_APP_NAME:
285*344aa361SAndroid Build Coastguard Worker         string_size = app_manifest_read_entry(iterator);
286*344aa361SAndroid Build Coastguard Worker         string = app_manifest_read_string(iterator, string_size, "app-name");
287*344aa361SAndroid Build Coastguard Worker         if (!string) {
288*344aa361SAndroid Build Coastguard Worker             goto error;
289*344aa361SAndroid Build Coastguard Worker         }
290*344aa361SAndroid Build Coastguard Worker 
291*344aa361SAndroid Build Coastguard Worker         entry->value.app_name = string;
292*344aa361SAndroid Build Coastguard Worker         iterator->app_name = string;
293*344aa361SAndroid Build Coastguard Worker         break;
294*344aa361SAndroid Build Coastguard Worker 
295*344aa361SAndroid Build Coastguard Worker     default:
296*344aa361SAndroid Build Coastguard Worker         TLOGE("manifest contains unknown config key %" PRIu32 " for app %s\n",
297*344aa361SAndroid Build Coastguard Worker               manifest_key, iterator->app_name);
298*344aa361SAndroid Build Coastguard Worker         goto error;
299*344aa361SAndroid Build Coastguard Worker     }
300*344aa361SAndroid Build Coastguard Worker 
301*344aa361SAndroid Build Coastguard Worker     assert(iterator->error == NO_ERROR);
302*344aa361SAndroid Build Coastguard Worker     entry->key = manifest_key;
303*344aa361SAndroid Build Coastguard Worker     if (out_error) {
304*344aa361SAndroid Build Coastguard Worker         *out_error = NO_ERROR;
305*344aa361SAndroid Build Coastguard Worker     }
306*344aa361SAndroid Build Coastguard Worker     return true;
307*344aa361SAndroid Build Coastguard Worker 
308*344aa361SAndroid Build Coastguard Worker error:
309*344aa361SAndroid Build Coastguard Worker     if (out_error) {
310*344aa361SAndroid Build Coastguard Worker         if (iterator->error != NO_ERROR) {
311*344aa361SAndroid Build Coastguard Worker             *out_error = iterator->error;
312*344aa361SAndroid Build Coastguard Worker         } else {
313*344aa361SAndroid Build Coastguard Worker             *out_error = ERR_NOT_VALID;
314*344aa361SAndroid Build Coastguard Worker         }
315*344aa361SAndroid Build Coastguard Worker     }
316*344aa361SAndroid Build Coastguard Worker     return false;
317*344aa361SAndroid Build Coastguard Worker }
318