1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <launchpad/launchpad.h>
6 #include <launchpad/vmo.h>
7 #include "elf.h"
8 
9 #include <zircon/assert.h>
10 #include <zircon/dlfcn.h>
11 #include <zircon/process.h>
12 #include <zircon/processargs.h>
13 #include <zircon/stack.h>
14 #include <zircon/syscalls.h>
15 #include <ldmsg/ldmsg.h>
16 #include <lib/fdio/io.h>
17 #include <assert.h>
18 #include <stdatomic.h>
19 #include <stdbool.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/param.h>
25 #include <threads.h>
26 
27 enum special_handles {
28     HND_LDSVC_LOADER,
29     HND_EXEC_VMO,
30     HND_SEGMENTS_VMAR,
31     HND_SPECIAL_COUNT
32 };
33 
34 struct launchpad {
35     uint32_t argc;
36     uint32_t envc;
37     uint32_t namec;
38     char* args;
39     size_t args_len;
40     char* env;
41     size_t env_len;
42     char* names;
43     size_t names_len;
44 
45     size_t num_script_args;
46     char* script_args;
47     size_t script_args_len;
48 
49     zx_handle_t* handles;
50     uint32_t* handles_info;
51     size_t handle_count;
52     size_t handle_alloc;
53 
54     const char* errmsg;
55     zx_status_t error;
56 
57     zx_vaddr_t entry;
58     zx_vaddr_t base;
59     zx_vaddr_t vdso_base;
60 
61     size_t stack_size;
62     bool set_stack_size;
63 
64     zx_handle_t special_handles[HND_SPECIAL_COUNT];
65     bool loader_message;
66 
67     zx_handle_t reserve_vmar;
68     bool fresh_process;
69 };
70 
71 // Returned when calloc() fails on create, so callers
72 // can still call all the various add handles functions
73 // which will discard the handles, etc, etc.
74 static launchpad_t invalid_launchpad = {
75     .errmsg = "create: could not allocate launchpad_t",
76     .error = ZX_ERR_NO_MEMORY,
77 };
78 
lp_error(launchpad_t * lp,zx_status_t error,const char * msg)79 static zx_status_t lp_error(launchpad_t* lp, zx_status_t error, const char* msg) {
80     if (lp->error == ZX_OK) {
81         lp->error = error;
82         lp->errmsg = msg;
83     }
84     return lp->error;
85 }
86 
launchpad_get_status(launchpad_t * lp)87 zx_status_t launchpad_get_status(launchpad_t* lp) {
88     return lp->error;
89 }
90 
launchpad_abort(launchpad_t * lp,zx_status_t error,const char * msg)91 void launchpad_abort(launchpad_t* lp, zx_status_t error, const char* msg) {
92     lp_error(lp, (error < 0) ? error : ZX_ERR_INTERNAL, msg);
93 }
94 
launchpad_error_message(launchpad_t * lp)95 const char* launchpad_error_message(launchpad_t* lp) {
96     return lp->errmsg;
97 }
98 
99 #define HND_LOADER_COUNT 3
100 // We always install the process handle as the first in the message.
101 #define lp_proc(lp) ((lp)->handles[0])
102 // We always install the vmar handle as the second in the message.
103 #define lp_vmar(lp) ((lp)->handles[1])
104 
launchpad_destroy(launchpad_t * lp)105 void launchpad_destroy(launchpad_t* lp) {
106     if (lp == &invalid_launchpad)
107         return;
108     zx_handle_close(lp->reserve_vmar);
109     zx_handle_close_many(lp->special_handles, HND_SPECIAL_COUNT);
110     zx_handle_close_many(lp->handles, lp->handle_count);
111     free(lp->handles);
112     free(lp->handles_info);
113     free(lp->script_args);
114     free(lp->args);
115     free(lp->env);
116     free(lp);
117 }
118 
launchpad_create_with_process(zx_handle_t proc,zx_handle_t vmar,launchpad_t ** result)119 zx_status_t launchpad_create_with_process(zx_handle_t proc,
120                                           zx_handle_t vmar,
121                                           launchpad_t** result) {
122     launchpad_t* lp = calloc(1, sizeof(*lp));
123     if (lp == NULL) {
124         lp = &invalid_launchpad;
125     } else {
126         lp->errmsg = "no error";
127     }
128 
129     if (launchpad_add_handle(lp, proc, PA_PROC_SELF) == ZX_OK) {
130         // If the process has an existing vDSO mapping, record it for
131         // use by launchpad_start_extra.
132         zx_status_t status = zx_object_get_property(
133             proc, ZX_PROP_PROCESS_VDSO_BASE_ADDRESS,
134             &lp->vdso_base, sizeof(lp->vdso_base));
135         if (status != ZX_OK)
136             lp_error(lp, status,
137                      "create: cannot get ZX_PROP_PROCESS_VDSO_BASE_ADDRESS");
138     }
139     launchpad_add_handle(lp, vmar, PA_VMAR_ROOT);
140 
141     *result = lp;
142     return lp->error;
143 }
144 
145 // Create a new process and a launchpad that will set it up.
launchpad_create_with_jobs(zx_handle_t creation_job,zx_handle_t transferred_job,const char * name,launchpad_t ** result)146 zx_status_t launchpad_create_with_jobs(zx_handle_t creation_job, zx_handle_t transferred_job,
147                                        const char* name, launchpad_t** result) {
148     uint32_t name_len = strlen(name);
149 
150     zx_handle_t proc = ZX_HANDLE_INVALID;
151     zx_handle_t vmar = ZX_HANDLE_INVALID;
152     zx_status_t status = zx_process_create(creation_job, name, name_len, 0, &proc, &vmar);
153 
154     launchpad_t* lp;
155     if (launchpad_create_with_process(proc, vmar, &lp) == ZX_OK)
156         lp->fresh_process = true;
157 
158     if (status < 0)
159         lp_error(lp, status, "create: zx_process_create() failed");
160 
161     if (transferred_job != ZX_HANDLE_INVALID) {
162         launchpad_add_handle(lp, transferred_job, PA_JOB_DEFAULT);
163     }
164 
165     *result = lp;
166     return lp->error;
167 }
168 
launchpad_create(zx_handle_t job,const char * name,launchpad_t ** result)169 zx_status_t launchpad_create(zx_handle_t job,
170                              const char* name, launchpad_t** result) {
171     if (job == ZX_HANDLE_INVALID)
172         job = zx_job_default();
173     zx_handle_t xjob = ZX_HANDLE_INVALID;
174     zx_handle_duplicate(job, ZX_RIGHT_SAME_RIGHTS, &xjob);
175     return launchpad_create_with_jobs(job, xjob, name, result);
176 }
177 
launchpad_get_process_handle(launchpad_t * lp)178 zx_handle_t launchpad_get_process_handle(launchpad_t* lp) {
179     return lp_proc(lp);
180 }
181 
launchpad_get_root_vmar_handle(launchpad_t * lp)182 zx_handle_t launchpad_get_root_vmar_handle(launchpad_t* lp) {
183     return lp_vmar(lp);
184 }
185 
build_stringtable(launchpad_t * lp,int count,const char * const * item,size_t * total_out,char ** out)186 static zx_status_t build_stringtable(launchpad_t* lp,
187                                     int count, const char* const* item,
188                                     size_t* total_out, char** out) {
189     if (lp->error)
190         return lp->error;
191     if (count < 0)
192         return lp_error(lp, ZX_ERR_INVALID_ARGS, "negative string array count");
193 
194     size_t total = 0;
195     for (int i = 0; i < count; ++i)
196         total += strlen(item[i]) + 1;
197 
198     char* buffer = NULL;
199     if (total > 0) {
200         buffer = malloc(total);
201         if (buffer == NULL)
202             return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for string array");
203 
204         char* p = buffer;
205         for (int i = 0; i < count; ++i)
206             p = stpcpy(p, item[i]) + 1;
207 
208         if ((size_t) (p - buffer) != total) {
209             // The strings changed in parallel.  Not kosher!
210             free(buffer);
211             return lp_error(lp, ZX_ERR_INVALID_ARGS, "string array modified during use");
212         }
213     }
214 
215     *total_out = total;
216     *out = buffer;
217     return ZX_OK;
218 }
219 
launchpad_set_args(launchpad_t * lp,int argc,const char * const * argv)220 zx_status_t launchpad_set_args(launchpad_t* lp,
221                                int argc, const char* const* argv) {
222     size_t total;
223     char* buffer;
224     zx_status_t r = build_stringtable(lp, argc, argv, &total, &buffer);
225     if (r < 0)
226         return r;
227 
228     free(lp->args);
229     lp->argc = argc;
230     lp->args = buffer;
231     lp->args_len = total;
232     return ZX_OK;
233 }
234 
launchpad_set_nametable(launchpad_t * lp,size_t count,const char * const * names)235 zx_status_t launchpad_set_nametable(launchpad_t* lp,
236                                     size_t count, const char* const* names) {
237     size_t total;
238     char* buffer;
239     zx_status_t r = build_stringtable(lp, count, names, &total, &buffer);
240     if (r < 0)
241         return r;
242 
243     free(lp->names);
244     lp->namec = count;
245     lp->names = buffer;
246     lp->names_len = total;
247     return ZX_OK;
248 }
249 
launchpad_set_environ(launchpad_t * lp,const char * const * envp)250 zx_status_t launchpad_set_environ(launchpad_t* lp, const char* const* envp) {
251     uint32_t count = 0;
252     if (envp != NULL) {
253         for (const char* const* ep = envp; *ep != NULL; ++ep) {
254             ++count;
255         }
256     }
257 
258     size_t total;
259     char* buffer;
260     zx_status_t r = build_stringtable(lp, count, envp, &total, &buffer);
261     if (r < 0)
262         return r;
263 
264     free(lp->env);
265     lp->envc = count;
266     lp->env = buffer;
267     lp->env_len = total;
268     return ZX_OK;
269 }
270 
more_handles(launchpad_t * lp,size_t n)271 static zx_status_t more_handles(launchpad_t* lp, size_t n) {
272     if (lp->error)
273         return lp->error;
274 
275     if (ZX_CHANNEL_MAX_MSG_HANDLES - lp->handle_count < n)
276         return lp_error(lp, ZX_ERR_NO_MEMORY, "too many handles for handle table");
277 
278     if (lp->handle_alloc - lp->handle_count < n) {
279         size_t alloc = lp->handle_alloc == 0 ? 8 : lp->handle_alloc * 2;
280         while (alloc - lp->handle_count < n)
281             alloc <<= 1;
282         zx_handle_t* handles = realloc(lp->handles,
283                                        alloc * sizeof(handles[0]));
284         if (handles == NULL)
285             return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for handle table");
286         lp->handles = handles;
287         uint32_t* info = realloc(lp->handles_info, alloc * sizeof(info[0]));
288         if (info == NULL)
289             return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for handle table");
290         lp->handles_info = info;
291         lp->handle_alloc = alloc;
292     }
293     return ZX_OK;
294 }
295 
launchpad_add_handle(launchpad_t * lp,zx_handle_t h,uint32_t id)296 zx_status_t launchpad_add_handle(launchpad_t* lp, zx_handle_t h, uint32_t id) {
297     if (h == ZX_HANDLE_INVALID)
298         return lp_error(lp, ZX_ERR_BAD_HANDLE, "added invalid handle");
299     zx_status_t status = more_handles(lp, 1);
300     if (status == ZX_OK) {
301         lp->handles[lp->handle_count] = h;
302         lp->handles_info[lp->handle_count] = id;
303         ++lp->handle_count;
304     } else {
305         zx_handle_close(h);
306     }
307     return status;
308 }
309 
launchpad_add_handles(launchpad_t * lp,size_t n,const zx_handle_t h[],const uint32_t id[])310 zx_status_t launchpad_add_handles(launchpad_t* lp, size_t n,
311                                   const zx_handle_t h[],
312                                   const uint32_t id[]) {
313     zx_status_t status = more_handles(lp, n);
314     if (status == ZX_OK) {
315         memcpy(&lp->handles[lp->handle_count], h, n * sizeof(h[0]));
316         memcpy(&lp->handles_info[lp->handle_count], id, n * sizeof(id[0]));
317         lp->handle_count += n;
318         for (size_t i = 0; i < n; i++) {
319             if (h[i] == ZX_HANDLE_INVALID) {
320                 return lp_error(lp, ZX_ERR_BAD_HANDLE, "added invalid handle");
321             }
322         }
323     } else {
324         for (size_t i = 0; i < n; i++) {
325             zx_handle_close(h[i]);
326         }
327     }
328     return status;
329 }
330 
331 //TODO: use transfer_fd here and eliminate fdio_pipe_half()
launchpad_add_pipe(launchpad_t * lp,int * fd_out,int target_fd)332 zx_status_t launchpad_add_pipe(launchpad_t* lp, int* fd_out, int target_fd) {
333     zx_handle_t handle;
334     uint32_t id;
335     int fd;
336 
337     if (lp->error)
338         return lp->error;
339     if ((target_fd < 0) || (target_fd >= FDIO_MAX_FD)) {
340         return lp_error(lp, ZX_ERR_INVALID_ARGS, "add_pipe: invalid target fd");
341     }
342     zx_status_t status;
343     if ((status = fdio_pipe_half(&handle, &id)) < 0) {
344         return lp_error(lp, status, "add_pipe: failed to create pipe");
345     }
346     fd = status;
347     if ((status = launchpad_add_handle(lp, handle, PA_HND(PA_HND_TYPE(id), target_fd))) < 0) {
348         close(fd);
349         zx_handle_close(handle);
350         return status;
351     }
352     *fd_out = fd;
353     return ZX_OK;
354 }
355 
check_elf_stack_size(launchpad_t * lp,elf_load_info_t * elf)356 static void check_elf_stack_size(launchpad_t* lp, elf_load_info_t* elf) {
357     size_t elf_stack_size = elf_load_get_stack_size(elf);
358     if (elf_stack_size > 0)
359         launchpad_set_stack_size(lp, elf_stack_size);
360 }
361 
launchpad_elf_load_basic(launchpad_t * lp,zx_handle_t vmo)362 zx_status_t launchpad_elf_load_basic(launchpad_t* lp, zx_handle_t vmo) {
363     if (vmo == ZX_HANDLE_INVALID)
364         return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load: invalid vmo");
365     if (lp->error)
366         goto done;
367 
368     elf_load_info_t* elf;
369     zx_status_t status;
370     if ((status = elf_load_start(vmo, NULL, 0, &elf)))
371         lp_error(lp, status, "elf_load: elf_load_start() failed");
372     zx_handle_t segments_vmar;
373     if ((status = elf_load_finish(lp_vmar(lp), elf, vmo,
374                                   &segments_vmar, &lp->base, &lp->entry)))
375         lp_error(lp, status, "elf_load: elf_load_finish() failed");
376     check_elf_stack_size(lp, elf);
377     elf_load_destroy(elf);
378 
379     if (status == ZX_OK) {
380         lp->loader_message = false;
381         launchpad_add_handle(lp, segments_vmar,
382                              PA_HND(PA_VMAR_LOADED, 0));
383     }
384 
385 done:
386     zx_handle_close(vmo);
387     return lp->error;
388 }
389 
launchpad_elf_load_extra(launchpad_t * lp,zx_handle_t vmo,zx_vaddr_t * base,zx_vaddr_t * entry)390 zx_status_t launchpad_elf_load_extra(launchpad_t* lp, zx_handle_t vmo,
391                                      zx_vaddr_t* base, zx_vaddr_t* entry) {
392     if (lp->error)
393         return lp->error;
394     if (vmo == ZX_HANDLE_INVALID)
395         return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load_extra: invalid vmo");
396 
397     elf_load_info_t* elf;
398     zx_status_t status;
399     if ((status = elf_load_start(vmo, NULL, 0, &elf)))
400         lp_error(lp, status, "elf_load_extra: elf_load_start() failed");
401     if ((status = elf_load_finish(lp_vmar(lp), elf, vmo, NULL, base, entry)))
402         lp_error(lp, status, "elf_load_extra: elf_load_finish() failed");
403     elf_load_destroy(elf);
404 
405     return lp->error;
406 }
407 
408 #define LOADER_SVC_MSG_MAX 1024
409 
loader_svc_rpc(zx_handle_t loader_svc,uint32_t ordinal,const void * data,size_t len,zx_handle_t * out)410 static zx_status_t loader_svc_rpc(zx_handle_t loader_svc, uint32_t ordinal,
411                                   const void* data, size_t len, zx_handle_t* out) {
412     static _Atomic zx_txid_t next_txid;
413 
414     ldmsg_req_t req;
415     memset(&req.header, 0, sizeof(req.header));
416     req.header.ordinal = ordinal;
417 
418     size_t req_len;
419     zx_status_t status = ldmsg_req_encode(&req, &req_len, data, len);
420     if (status != ZX_OK)
421         return status;
422 
423     req.header.txid = atomic_fetch_add(&next_txid, 1);
424 
425     ldmsg_rsp_t rsp;
426     memset(&rsp, 0, sizeof(rsp));
427 
428     zx_handle_t handle = ZX_HANDLE_INVALID;
429     const zx_channel_call_args_t call = {
430         .wr_bytes = &req,
431         .wr_num_bytes = req_len,
432         .rd_bytes = &rsp,
433         .rd_num_bytes = sizeof(rsp),
434         .rd_handles = &handle,
435         .rd_num_handles = 1,
436     };
437     uint32_t reply_size;
438     uint32_t handle_count;
439     status = zx_channel_call(loader_svc, 0, ZX_TIME_INFINITE, &call, &reply_size, &handle_count);
440     if (status != ZX_OK)
441         return status;
442 
443     // Check for protocol violations.
444     if (reply_size != ldmsg_rsp_get_size(&rsp)) {
445     protocol_violation:
446         zx_handle_close(handle);
447         return ZX_ERR_BAD_STATE;
448     }
449     if (rsp.header.ordinal != ordinal)
450         goto protocol_violation;
451 
452     if (rsp.rv != ZX_OK) {
453         if (handle != ZX_HANDLE_INVALID)
454             goto protocol_violation;
455         if (rsp.rv > 0)
456             goto protocol_violation;
457         *out = ZX_HANDLE_INVALID;
458     } else {
459         *out = handle_count ? handle : ZX_HANDLE_INVALID;
460     }
461     return rsp.rv;
462 }
463 
setup_loader_svc(launchpad_t * lp)464 static zx_status_t setup_loader_svc(launchpad_t* lp) {
465     if (lp->special_handles[HND_LDSVC_LOADER] != ZX_HANDLE_INVALID)
466         return ZX_OK;
467 
468     zx_handle_t loader_svc;
469     zx_status_t status = dl_clone_loader_service(&loader_svc);
470     if (status < 0)
471         return status;
472 
473     lp->special_handles[HND_LDSVC_LOADER] = loader_svc;
474     return ZX_OK;
475 }
476 
477 // Reserve roughly the low half of the address space, so the new
478 // process can use sanitizers that need to allocate shadow memory there.
479 // The reservation VMAR is kept around just long enough to make sure all
480 // the initial allocations (mapping in the initial ELF objects, and
481 // allocating the initial stack) stay out of this area, and then destroyed.
482 // The process's own allocations can then use the full address space; if
483 // it's using a sanitizer, it will set up its shadow memory first thing.
reserve_low_address_space(launchpad_t * lp)484 static zx_status_t reserve_low_address_space(launchpad_t* lp) {
485     if (lp->reserve_vmar != ZX_HANDLE_INVALID)
486         return ZX_OK;
487 
488     zx_info_vmar_t info;
489     zx_status_t status = zx_object_get_info(lp_vmar(lp), ZX_INFO_VMAR,
490                                             &info, sizeof(info), NULL, NULL);
491     if (status != ZX_OK) {
492         return lp_error(lp, status,
493                         "zx_object_get_info failed on child root VMAR handle");
494     }
495 
496     uintptr_t addr;
497     size_t reserve_size =
498         (((info.base + info.len) / 2) + PAGE_SIZE - 1) & -PAGE_SIZE;
499     status = zx_vmar_allocate(lp_vmar(lp), ZX_VM_SPECIFIC, 0,
500                               reserve_size - info.base,
501                               &lp->reserve_vmar, &addr);
502     if (status != ZX_OK) {
503         return lp_error(
504             lp, status,
505             "zx_vmar_allocate failed for low address space reservation");
506     }
507 
508     if (addr != info.base) {
509         return lp_error(lp, ZX_ERR_BAD_STATE,
510                         "zx_vmar_allocate gave wrong address?!?");
511     }
512 
513     return ZX_OK;
514 }
515 
516 // Consumes 'vmo' on success, not on failure.
handle_interp(launchpad_t * lp,zx_handle_t vmo,const char * interp,size_t interp_len)517 static zx_status_t handle_interp(launchpad_t* lp, zx_handle_t vmo,
518                                  const char* interp, size_t interp_len) {
519     zx_status_t status = setup_loader_svc(lp);
520     if (status != ZX_OK)
521         return status;
522 
523     zx_handle_t interp_vmo;
524     status = loader_svc_rpc(
525         lp->special_handles[HND_LDSVC_LOADER], LDMSG_OP_LOAD_OBJECT,
526         interp, interp_len, &interp_vmo);
527     if (status != ZX_OK)
528         return status;
529 
530     if (lp->fresh_process) {
531         // A fresh process using PT_INTERP might be loading a libc.so that
532         // supports sanitizers, so in that case (the most common case)
533         // keep the mappings launchpad makes out of the low address region.
534         status = reserve_low_address_space(lp);
535         if (status != ZX_OK)
536             return status;
537     }
538 
539     elf_load_info_t* elf;
540     zx_handle_t segments_vmar;
541     status = elf_load_start(interp_vmo, NULL, 0, &elf);
542     if (status == ZX_OK) {
543         status = elf_load_finish(lp_vmar(lp), elf, interp_vmo,
544                                  &segments_vmar, &lp->base, &lp->entry);
545         elf_load_destroy(elf);
546     }
547     zx_handle_close(interp_vmo);
548 
549     if (status == ZX_OK) {
550         if (lp->special_handles[HND_EXEC_VMO] != ZX_HANDLE_INVALID)
551             zx_handle_close(lp->special_handles[HND_EXEC_VMO]);
552         lp->special_handles[HND_EXEC_VMO] = vmo;
553         if (lp->special_handles[HND_SEGMENTS_VMAR] != ZX_HANDLE_INVALID)
554             zx_handle_close(lp->special_handles[HND_SEGMENTS_VMAR]);
555         lp->special_handles[HND_SEGMENTS_VMAR] = segments_vmar;
556         lp->loader_message = true;
557     }
558 
559     return status;
560 }
561 
launchpad_elf_load_body(launchpad_t * lp,const char * hdr_buf,size_t buf_sz,zx_handle_t vmo)562 static zx_status_t launchpad_elf_load_body(launchpad_t* lp, const char* hdr_buf,
563                                            size_t buf_sz, zx_handle_t vmo) {
564     elf_load_info_t* elf;
565     zx_status_t status;
566 
567     if (lp->error)
568         goto done;
569     if ((status = elf_load_start(vmo, hdr_buf, buf_sz, &elf)) != ZX_OK) {
570         lp_error(lp, status, "elf_load: elf_load_start() failed");
571     } else {
572         char* interp;
573         size_t interp_len;
574         status = elf_load_get_interp(elf, vmo, &interp, &interp_len);
575         if (status != ZX_OK) {
576             lp_error(lp, status, "elf_load: get_interp() failed");
577         } else {
578             if (interp == NULL) {
579                 zx_handle_t segments_vmar;
580                 status = elf_load_finish(lp_vmar(lp), elf, vmo, &segments_vmar,
581                                          &lp->base, &lp->entry);
582                 if (status != ZX_OK) {
583                     lp_error(lp, status, "elf_load: elf_load_finish() failed");
584                 } else {
585                     // With no PT_INTERP, we obey PT_GNU_STACK.p_memsz for
586                     // the stack size setting.  With PT_INTERP, the dynamic
587                     // linker is responsible for that.
588                     check_elf_stack_size(lp, elf);
589                     lp->loader_message = false;
590                     launchpad_add_handle(
591                         lp, segments_vmar,
592                         PA_HND(PA_VMAR_LOADED, 0));
593                 }
594             } else {
595                 if ((status = handle_interp(lp, vmo, interp, interp_len))) {
596                     lp_error(lp, status, "elf_load: handle_interp failed");
597                 } else {
598                     // handle_interp() takes ownership of vmo on success
599                     vmo = ZX_HANDLE_INVALID;
600                 }
601                 free(interp);
602             }
603         }
604         elf_load_destroy(elf);
605     }
606 done:
607     if (vmo)
608         zx_handle_close(vmo);
609     return lp->error;
610 }
611 
612 // Find the starting point of the interpreter and the interpreter
613 // arguments in a #! script header. Note that the input buffer (line)
614 // will be modified to add a NULL after the interpreter name.
parse_interp_spec(char * line,char ** interp_start,size_t * interp_len,char ** args_start)615 static zx_status_t parse_interp_spec(char *line, char **interp_start,
616                                      size_t *interp_len, char **args_start)
617 {
618     *args_start = NULL;
619 
620     // Skip the '#!' prefix
621     char* next_char = line + 2;
622 
623     // Skip whitespace
624     next_char += strspn(next_char, " \t");
625 
626     // No interpreter specified
627     if (*next_char == '\0')
628         return ZX_ERR_NOT_FOUND;
629 
630     *interp_start = next_char;
631 
632     // Skip the interpreter name
633     next_char += strcspn(next_char, " \t");
634     *interp_len = next_char - *interp_start;
635 
636     if (*next_char == '\0')
637         return ZX_OK;
638 
639     *next_char++ = '\0';
640 
641     // Look for the args
642     next_char += strspn(next_char, " \t");
643 
644     if (*next_char == '\0')
645         return ZX_OK;
646 
647     *args_start = next_char;
648     return ZX_OK;
649 }
650 
launchpad_file_load(launchpad_t * lp,zx_handle_t vmo)651 zx_status_t launchpad_file_load(launchpad_t* lp, zx_handle_t vmo) {
652     if (vmo == ZX_HANDLE_INVALID)
653         return lp_error(lp, ZX_ERR_INVALID_ARGS, "file_load: invalid vmo");
654 
655     if (lp->script_args != NULL) {
656         free(lp->script_args);
657         lp->script_args = NULL;
658     }
659     lp->script_args_len = 0;
660     lp->num_script_args = 0;
661 
662     size_t script_nest_level = 0;
663 
664     char first_line[LP_MAX_INTERP_LINE_LEN + 1];
665     size_t to_read = sizeof(first_line);
666     size_t vmo_size;
667     zx_status_t status = zx_vmo_get_size(vmo, &vmo_size);
668     if (status != ZX_OK) {
669         return lp_error(lp, status, "file_load: zx_vmo_get_size() failed");
670     }
671     if (to_read > vmo_size) {
672         to_read = vmo_size;
673     }
674 
675     while (1) {
676         // Read enough to get the interpreter specification of a script
677         status = zx_vmo_read(vmo, first_line, 0, to_read);
678 
679         // This is not a script -- load as an ELF file
680         if ((status == ZX_OK)
681             && (to_read < 2 || first_line[0] != '#' || first_line[1] != '!'))
682             break;
683 
684         zx_handle_close(vmo);
685 
686         if (status != ZX_OK)
687             return lp_error(lp, status, "file_load: zx_vmo_read() failed");
688 
689         script_nest_level++;
690 
691         // No point trying to read an interpreter we're not going to consider
692         if (script_nest_level > LP_MAX_SCRIPT_NEST_LEVEL)
693             return lp_error(lp, ZX_ERR_NOT_SUPPORTED,
694                             "file_load: too many levels of script indirection");
695 
696         // Normalize the line so that it is NULL-terminated
697         char* newline_pos = memchr(first_line, '\n', to_read);
698         if (newline_pos)
699             *newline_pos = '\0';
700         else if (to_read == sizeof(first_line))
701             return lp_error(lp, ZX_ERR_OUT_OF_RANGE,
702                             "file_load: first line of script too long");
703         else
704             first_line[to_read] = '\0';
705 
706         char* interp_start;
707         size_t interp_len;
708         char* args_start;
709         status = parse_interp_spec(first_line, &interp_start, &interp_len,
710                                    &args_start);
711         if (status != ZX_OK)
712             return lp_error(lp, status,
713                             "file_load: failed to parse interpreter spec");
714 
715         size_t args_len = (args_start == NULL) ? 0 : newline_pos - args_start;
716 
717         // Add interpreter and args to start of lp->script_args
718         size_t new_args_len = interp_len + 1;
719         if (args_start != NULL)
720             new_args_len += args_len + 1;
721         char *new_buf = malloc(new_args_len + lp->script_args_len);
722         if (new_buf == NULL)
723             return lp_error(lp, ZX_ERR_NO_MEMORY, "file_load: out of memory");
724 
725         memcpy(new_buf, interp_start, interp_len + 1);
726         lp->num_script_args++;
727 
728         if (args_start != NULL) {
729             memcpy(&new_buf[interp_len + 1], args_start, args_len + 1);
730             lp->num_script_args++;
731         }
732 
733         if (lp->script_args != NULL) {
734             memcpy(&new_buf[new_args_len], lp->script_args,
735                    lp->script_args_len);
736             free(lp->script_args);
737         }
738 
739         lp->script_args = new_buf;
740         lp->script_args_len += new_args_len;
741 
742         // Load the interpreter into memory
743         status = setup_loader_svc(lp);
744         if (status != ZX_OK)
745             return lp_error(lp, status, "file_load: setup_loader_svc() failed");
746 
747         status = loader_svc_rpc(lp->special_handles[HND_LDSVC_LOADER],
748                              LDMSG_OP_LOAD_SCRIPT_INTERPRETER,
749                              interp_start, interp_len, &vmo);
750         if (status != ZX_OK)
751             return lp_error(lp, status, "file_load: loader_svc_rpc() failed");
752     }
753 
754     // Finally, load the interpreter itself
755     status = launchpad_elf_load_body(lp, first_line, to_read, vmo);
756 
757     if (status != ZX_OK)
758         lp_error(lp, status, "file_load: failed to load ELF file");
759 
760     return status;
761 }
762 
launchpad_elf_load(launchpad_t * lp,zx_handle_t vmo)763 zx_status_t launchpad_elf_load(launchpad_t* lp, zx_handle_t vmo) {
764     if (vmo == ZX_HANDLE_INVALID)
765         return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load: invalid vmo");
766 
767     return launchpad_elf_load_body(lp, NULL, 0, vmo);
768 }
769 
770 static zx_handle_t vdso_vmo = ZX_HANDLE_INVALID;
771 static mtx_t vdso_mutex = MTX_INIT;
vdso_lock(void)772 static void vdso_lock(void) __TA_ACQUIRE(&vdso_mutex) {
773     mtx_lock(&vdso_mutex);
774 }
vdso_unlock(void)775 static void vdso_unlock(void) __TA_RELEASE(&vdso_mutex) {
776     mtx_unlock(&vdso_mutex);
777 }
vdso_get_vmo(void)778 static zx_handle_t vdso_get_vmo(void) {
779     if (vdso_vmo == ZX_HANDLE_INVALID)
780         vdso_vmo = zx_take_startup_handle(PA_HND(PA_VMO_VDSO, 0));
781     return vdso_vmo;
782 }
783 
launchpad_get_vdso_vmo(zx_handle_t * out)784 zx_status_t launchpad_get_vdso_vmo(zx_handle_t* out) {
785     vdso_lock();
786     zx_status_t status = zx_handle_duplicate(vdso_get_vmo(),
787                                              ZX_RIGHT_SAME_RIGHTS, out);
788     vdso_unlock();
789     return status;
790 }
791 
launchpad_set_vdso_vmo(zx_handle_t new_vdso_vmo)792 zx_handle_t launchpad_set_vdso_vmo(zx_handle_t new_vdso_vmo) {
793     vdso_lock();
794     zx_handle_t old = vdso_vmo;
795     vdso_vmo = new_vdso_vmo;
796     vdso_unlock();
797     return old;
798 }
799 
launchpad_add_vdso_vmo(launchpad_t * lp)800 zx_status_t launchpad_add_vdso_vmo(launchpad_t* lp) {
801     if (lp->error)
802         return lp->error;
803     zx_handle_t vdso;
804     zx_status_t status;
805     if ((status = launchpad_get_vdso_vmo(&vdso)) != ZX_OK)
806         return lp_error(lp, status, "add_vdso_vmo: get_vdso_vmo failed");
807     // Takes ownership of 'vdso'.
808     return launchpad_add_handle(lp, vdso, PA_HND(PA_VMO_VDSO, 0));
809 }
810 
launchpad_load_vdso(launchpad_t * lp,zx_handle_t vmo)811 zx_status_t launchpad_load_vdso(launchpad_t* lp, zx_handle_t vmo) {
812     if (vmo != ZX_HANDLE_INVALID)
813         return launchpad_elf_load_extra(lp, vmo, &lp->vdso_base, NULL);
814     vdso_lock();
815     vmo = vdso_get_vmo();
816     zx_status_t status = launchpad_elf_load_extra(lp, vmo,
817                                                   &lp->vdso_base, NULL);
818     vdso_unlock();
819     return status;
820 }
821 
launchpad_get_entry_address(launchpad_t * lp,zx_vaddr_t * entry)822 zx_status_t launchpad_get_entry_address(launchpad_t* lp, zx_vaddr_t* entry) {
823     if (lp->entry == 0)
824         return ZX_ERR_BAD_STATE;
825     *entry = lp->entry;
826     return ZX_OK;
827 }
828 
launchpad_get_base_address(launchpad_t * lp,zx_vaddr_t * base)829 zx_status_t launchpad_get_base_address(launchpad_t* lp, zx_vaddr_t* base) {
830     if (lp->base == 0)
831         return ZX_ERR_BAD_STATE;
832     *base = lp->base;
833     return ZX_OK;
834 }
835 
launchpad_send_loader_message(launchpad_t * lp,bool do_send)836 bool launchpad_send_loader_message(launchpad_t* lp, bool do_send) {
837     bool result = lp->loader_message;
838     if (!lp->error)
839         lp->loader_message = do_send;
840     return result;
841 }
842 
launchpad_use_loader_service(launchpad_t * lp,zx_handle_t svc)843 zx_handle_t launchpad_use_loader_service(launchpad_t* lp, zx_handle_t svc) {
844     zx_handle_t result = lp->special_handles[HND_LDSVC_LOADER];
845     lp->special_handles[HND_LDSVC_LOADER] = svc;
846     return result;
847 }
848 
849 // Construct a load message. Fill in the header, args, and environment
850 // fields, and leave space for the handles, which should be filled in
851 // by the caller.
852 // TODO(mcgrathr): One day we'll have a gather variant of message_write
853 // and then we can send this without copying into a temporary buffer.
build_message(launchpad_t * lp,size_t num_handles,void ** msg_buf,size_t * buf_size,bool with_names)854 static zx_status_t build_message(launchpad_t* lp, size_t num_handles,
855                                  void** msg_buf, size_t* buf_size,
856                                  bool with_names) {
857 
858     size_t msg_size = sizeof(zx_proc_args_t);
859     static_assert(sizeof(zx_proc_args_t) % sizeof(uint32_t) == 0,
860                   "handles misaligned in load message");
861     msg_size += sizeof(uint32_t) * num_handles;
862     msg_size += lp->script_args_len;
863     msg_size += lp->args_len;
864     msg_size += lp->env_len;
865     msg_size += lp->names_len;
866     void* msg = malloc(msg_size);
867     if (msg == NULL)
868         return ZX_ERR_NO_MEMORY;
869 
870     zx_proc_args_t* header = msg;
871 
872     memset(header, 0, sizeof(*header));
873     header->protocol = ZX_PROCARGS_PROTOCOL;
874     header->version = ZX_PROCARGS_VERSION;
875     header->handle_info_off = sizeof(*header);
876 
877     // Include the argument strings so the dynamic linker can use argv[0]
878     // in messages it prints.
879     header->args_off = header->handle_info_off +
880                        sizeof(uint32_t) * num_handles;
881     header->args_num = lp->num_script_args + lp->argc;
882     if (header->args_num > 0) {
883         uint8_t* script_args_start = (uint8_t*)msg + header->args_off;
884         memcpy(script_args_start, lp->script_args, lp->script_args_len);
885         uint8_t* args_start = script_args_start + lp->script_args_len;
886         memcpy(args_start, lp->args, lp->args_len);
887     }
888     size_t total_args_len = lp->script_args_len + lp->args_len;
889 
890     // Include the environment strings so the dynamic linker can
891     // see options like LD_DEBUG or whatnot.
892     if (lp->envc > 0) {
893         header->environ_off = header->args_off + total_args_len;
894         header->environ_num = lp->envc;
895         uint8_t* env_start = (uint8_t*)msg + header->environ_off;
896         memcpy(env_start, lp->env, lp->env_len);
897     }
898 
899     if (with_names && (lp->namec > 0)) {
900         header->names_off = header->args_off + total_args_len + lp->env_len;
901         header->names_num = lp->namec;
902         uint8_t* names_start = (uint8_t*)msg + header->names_off;
903         memcpy(names_start, lp->names, lp->names_len);
904     }
905 
906     *msg_buf = msg;
907     *buf_size = msg_size;
908     return ZX_OK;
909 }
910 
send_loader_message(launchpad_t * lp,zx_handle_t first_thread,zx_handle_t tochannel)911 static zx_status_t send_loader_message(launchpad_t* lp,
912                                        zx_handle_t first_thread,
913                                        zx_handle_t tochannel) {
914     void* msg;
915     size_t msg_size;
916     size_t num_handles = HND_SPECIAL_COUNT + HND_LOADER_COUNT;
917 
918     zx_status_t status = build_message(lp, num_handles, &msg, &msg_size, false);
919     if (status != ZX_OK)
920         return status;
921 
922     zx_proc_args_t* header = msg;
923     uint32_t* msg_handle_info;
924     msg_handle_info = (uint32_t*) ((uint8_t*)msg + header->handle_info_off);
925 
926     // This loop should be completely unrolled.  But using a switch here
927     // gives us compiler warnings if we forget to handle any of the special
928     // types listed in the enum.
929     zx_handle_t handles[HND_SPECIAL_COUNT + HND_LOADER_COUNT];
930     size_t nhandles = 0;
931     for (enum special_handles i = 0; i <= HND_SPECIAL_COUNT; ++i) {
932         uint32_t id = 0; // -Wall
933         switch (i) {
934         case HND_SPECIAL_COUNT:;
935             // Duplicate the handles for the loader so we can send them in the
936             // loader message and still have them later.
937             zx_handle_t proc;
938             status = zx_handle_duplicate(lp_proc(lp), ZX_RIGHT_SAME_RIGHTS, &proc);
939             if (status != ZX_OK) {
940                 free(msg);
941                 return status;
942             }
943             zx_handle_t vmar;
944             status = zx_handle_duplicate(lp_vmar(lp), ZX_RIGHT_SAME_RIGHTS, &vmar);
945             if (status != ZX_OK) {
946                 zx_handle_close(proc);
947                 free(msg);
948                 return status;
949             }
950             zx_handle_t thread;
951             status = zx_handle_duplicate(first_thread, ZX_RIGHT_SAME_RIGHTS, &thread);
952             if (status != ZX_OK) {
953                 zx_handle_close(proc);
954                 zx_handle_close(vmar);
955                 free(msg);
956                 return status;
957             }
958             handles[nhandles] = proc;
959             msg_handle_info[nhandles] = PA_PROC_SELF;
960             handles[nhandles + 1] = vmar;
961             msg_handle_info[nhandles + 1] = PA_VMAR_ROOT;
962             handles[nhandles + 2] = thread;
963             msg_handle_info[nhandles + 2] = PA_THREAD_SELF;
964             nhandles += HND_LOADER_COUNT;
965             continue;
966 
967         case HND_LDSVC_LOADER:
968             id = PA_LDSVC_LOADER;
969             break;
970 
971         case HND_EXEC_VMO:
972             id = PA_VMO_EXECUTABLE;
973             break;
974 
975         case HND_SEGMENTS_VMAR:
976             id = PA_VMAR_LOADED;
977             break;
978         }
979         if (lp->special_handles[i] != ZX_HANDLE_INVALID) {
980             handles[nhandles] = lp->special_handles[i];
981             msg_handle_info[nhandles] = id;
982             ++nhandles;
983         }
984     }
985 
986     status = zx_channel_write(tochannel, 0, msg, msg_size, handles, nhandles);
987     if (status == ZX_OK)
988         lp->loader_message = false;
989 
990     // message_write consumed all those handles.
991     for (enum special_handles i = 0; i < HND_SPECIAL_COUNT; ++i)
992         lp->special_handles[i] = ZX_HANDLE_INVALID;
993 
994     free(msg);
995     return status;
996 }
997 
launchpad_set_stack_size(launchpad_t * lp,size_t new_size)998 size_t launchpad_set_stack_size(launchpad_t* lp, size_t new_size) {
999     size_t old_size = lp->stack_size;
1000     if (new_size >= (SIZE_MAX & -PAGE_SIZE)) {
1001         // Ridiculously large size won't actually work at allocation time,
1002         // but at least page rounding won't wrap it around to zero.
1003         new_size = SIZE_MAX & -PAGE_SIZE;
1004     } else if (new_size > 0) {
1005         // Round up to page size.
1006         new_size = (new_size + PAGE_SIZE - 1) & -PAGE_SIZE;
1007     }
1008     if (lp->error == ZX_OK) {
1009         lp->stack_size = new_size;
1010         lp->set_stack_size = true;
1011     }
1012     return old_size;
1013 }
1014 
prepare_start(launchpad_t * lp,launchpad_start_data_t * result)1015 static zx_status_t prepare_start(launchpad_t* lp, launchpad_start_data_t* result) {
1016     if (lp->entry == 0)
1017         return lp_error(lp, ZX_ERR_BAD_STATE, "prepare start bad state");
1018 
1019     zx_status_t status = ZX_OK;
1020     zx_handle_t to_child = ZX_HANDLE_INVALID;
1021     zx_handle_t bootstrap = ZX_HANDLE_INVALID;
1022     zx_handle_t process = ZX_HANDLE_INVALID;
1023     zx_handle_t root_vmar = ZX_HANDLE_INVALID;
1024     zx_handle_t thread = ZX_HANDLE_INVALID;
1025     void *msg = NULL;
1026 
1027     status = zx_channel_create(0, &to_child, &bootstrap);
1028     if (status != ZX_OK)
1029         return lp_error(lp, status, "start: cannot create channel");
1030 
1031     const char* thread_name = "initial-thread";
1032     status = zx_thread_create(lp_proc(lp), thread_name, strlen(thread_name), 0, &thread);
1033     if (status != ZX_OK) {
1034         lp_error(lp, status, "cannot create initial thread");
1035         goto cleanup;
1036     }
1037 
1038     // Pass the thread handle down to the child.  The handle we pass
1039     // will be consumed by message_write.  So we need a duplicate to
1040     // pass to zx_process_start later.
1041     zx_handle_t thread_copy;
1042     status = zx_handle_duplicate(thread, ZX_RIGHT_SAME_RIGHTS, &thread_copy);
1043     if (status != ZX_OK) {
1044         lp_error(lp, status, "cannot duplicate thread handle");
1045         goto cleanup;
1046     }
1047 
1048     status = launchpad_add_handle(lp, thread_copy, PA_THREAD_SELF);
1049     if (status != ZX_OK) {
1050         lp_error(lp, status, "cannot add thread self handle");
1051         goto cleanup;
1052     }
1053 
1054     bool sent_loader_message = lp->loader_message;
1055     if (lp->loader_message) {
1056         status = send_loader_message(lp, thread, to_child);
1057         if (status != ZX_OK) {
1058             lp_error(lp, status, "failed to send loader message");
1059             goto cleanup;
1060         }
1061     }
1062 
1063     bool allocate_stack = !lp->set_stack_size || lp->stack_size > 0;
1064 
1065     size_t size;
1066     if (build_message(lp, lp->handle_count + (allocate_stack ? 1 : 0),
1067                       &msg, &size, true) != ZX_OK) {
1068         lp_error(lp, ZX_ERR_NO_MEMORY,
1069                  "out of memory assembling procargs message");
1070         goto cleanup;
1071     }
1072     zx_proc_args_t* header = msg;
1073     uint32_t* next_handle = mempcpy((uint8_t*)msg + header->handle_info_off,
1074                                     lp->handles_info,
1075                                     lp->handle_count * sizeof(lp->handles_info[0]));
1076     if (allocate_stack)
1077         *next_handle = PA_VMO_STACK;
1078 
1079     // Figure out how big an initial thread to allocate.
1080     char stack_vmo_name[ZX_MAX_NAME_LEN];
1081     size_t stack_size;
1082     if (sent_loader_message && !lp->set_stack_size) {
1083         // The initial stack will be used just for startup work and to
1084         // contain the bootstrap message.  Make it only as big as needed:
1085         // the message itself and its array of handles, plus some slop.
1086         stack_size = size + (lp->handle_count * sizeof(zx_handle_t));
1087 
1088         // This constant is defined by the C library in <limits.h>.  It's
1089         // tuned to be enough to cover the dynamic linker and C library
1090         // startup code's stack usage (up until the point it switches to
1091         // its own stack in __libc_start_main), but leave a little space so
1092         // for small bootstrap message sizes the stack needs only one page.
1093         stack_size += PTHREAD_STACK_MIN;
1094         stack_size = (stack_size + PAGE_SIZE - 1) & -PAGE_SIZE;
1095 
1096         snprintf(stack_vmo_name, sizeof(stack_vmo_name),
1097                  "stack: msg of %#zx", size);
1098     } else {
1099         // Use the requested or default size.
1100         stack_size =
1101             lp->set_stack_size ? lp->stack_size : ZIRCON_DEFAULT_STACK_SIZE;
1102         snprintf(stack_vmo_name, sizeof(stack_vmo_name), "stack: %s %#zx",
1103                  lp->set_stack_size ? "explicit" : "default", stack_size);
1104 
1105         // Assume the process will read the bootstrap message onto its
1106         // initial thread's stack.  If it would need more than half its
1107         // stack just to read the message, consider that an unreasonably
1108         // large size for the message (presumably arguments and
1109         // environment strings that are unreasonably large).
1110         if (stack_size > 0 && size > stack_size / 2) {
1111             lp_error(lp, ZX_ERR_BUFFER_TOO_SMALL,
1112                      "procargs message is too large");
1113             goto cleanup;
1114         }
1115     }
1116 
1117     zx_vaddr_t sp = 0;
1118     if (stack_size > 0) {
1119         // Allocate the initial thread's stack.
1120         zx_handle_t stack_vmo;
1121         zx_status_t status = zx_vmo_create(stack_size, 0, &stack_vmo);
1122         if (status != ZX_OK) {
1123             lp_error(lp, status, "cannot create stack vmo");
1124             goto cleanup;
1125         }
1126         zx_object_set_property(stack_vmo, ZX_PROP_NAME,
1127                                stack_vmo_name, strlen(stack_vmo_name));
1128         zx_vaddr_t stack_base;
1129         status = zx_vmar_map(lp_vmar(lp),
1130                               ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
1131                               0, stack_vmo, 0, stack_size, &stack_base);
1132         if (status == ZX_OK) {
1133             ZX_DEBUG_ASSERT(stack_size % PAGE_SIZE == 0);
1134             sp = compute_initial_stack_pointer(stack_base, stack_size);
1135             // Pass the stack VMO to the process.  Our protocol with the
1136             // new process is that we warrant that this is the VMO from
1137             // which the initial stack is mapped and that we've exactly
1138             // mapped the entire thing, so vm_object_get_size on this in
1139             // concert with the initial SP value tells it the exact bounds
1140             // of its stack.
1141             //
1142             // Note this expands the handle list after we've already
1143             // built the bootstrap message.  We shoved an extra info
1144             // slot with PA_VMO_STACK into the message, so now this new
1145             // final handle will correspond to that slot.
1146             status = launchpad_add_handle(lp, stack_vmo, PA_VMO_STACK);
1147         }
1148         if (status != ZX_OK) {
1149             zx_handle_close(stack_vmo);
1150             lp_error(lp, status, "cannot map stack vmo");
1151             goto cleanup;
1152         }
1153     }
1154 
1155     if (lp->reserve_vmar != ZX_HANDLE_INVALID) {
1156         // We're done doing mappings, so clear out the reservation VMAR.
1157         status = zx_vmar_destroy(lp->reserve_vmar);
1158         if (status != ZX_OK) {
1159             lp_error(lp, status, "\
1160 zx_vmar_destroy failed on low address space reservation VMAR");
1161             goto cleanup;
1162         }
1163         status = zx_handle_close(lp->reserve_vmar);
1164         if (status != ZX_OK) {
1165             lp_error(lp, status, "\
1166 zx_handle_close failed on low address space reservation VMAR");
1167             goto cleanup;
1168         }
1169         lp->reserve_vmar = ZX_HANDLE_INVALID;
1170     }
1171 
1172     // The process handle in lp->handles[0] will be consumed by message_write.
1173     // So we'll need a duplicate to do process operations later.
1174     status = zx_handle_duplicate(lp_proc(lp), ZX_RIGHT_SAME_RIGHTS, &process);
1175     if (status != ZX_OK) {
1176         lp_error(lp, status, "cannot duplicate process handle");
1177         goto cleanup;
1178     }
1179 
1180     // The root_vmar handle in lp->handles[0] will be consumed by message_write.
1181     // So we'll need a duplicate to do process operations later.
1182     status = zx_handle_duplicate(lp_vmar(lp), ZX_RIGHT_SAME_RIGHTS, &root_vmar);
1183     if (status != ZX_OK) {
1184         lp_error(lp, status, "cannot duplicate root vmar handle");
1185         goto cleanup;
1186     }
1187 
1188     status = zx_channel_write(to_child, 0, msg, size, lp->handles, lp->handle_count);
1189 
1190     // message_write consumed all the handles.
1191     for (size_t i = 0; i < lp->handle_count; ++i)
1192         lp->handles[i] = ZX_HANDLE_INVALID;
1193     lp->handle_count = 0;
1194 
1195     if (status != ZX_OK) {
1196         lp_error(lp, status, "failed to write procargs message");
1197         goto cleanup;
1198     }
1199 
1200     zx_handle_close(to_child);
1201     free(msg);
1202 
1203     result->process = process;
1204     result->root_vmar = root_vmar;
1205     result->thread = thread;
1206     result->entry = lp->entry;
1207     result->sp = sp;
1208     result->bootstrap = bootstrap;
1209     result->vdso_base = lp->vdso_base;
1210     result->base = lp->base;
1211     return ZX_OK;
1212 
1213 cleanup:
1214     if (to_child != ZX_HANDLE_INVALID)
1215        zx_handle_close(to_child);
1216     if (bootstrap != ZX_HANDLE_INVALID)
1217        zx_handle_close(bootstrap);
1218     if (process != ZX_HANDLE_INVALID)
1219        zx_handle_close(process);
1220     if (root_vmar != ZX_HANDLE_INVALID)
1221        zx_handle_close(root_vmar);
1222     if (thread != ZX_HANDLE_INVALID)
1223        zx_handle_close(thread);
1224     free(msg);
1225     return lp->error;
1226 }
1227 
1228 // Start the process running.  If the send_loader_message flag is
1229 // set and this succeeds in sending the initial bootstrap message,
1230 // it clears the loader-service handle.  If this succeeds in sending
1231 // the main bootstrap message, it clears the list of handles to
1232 // transfer (after they've been transferred) as well as the process
1233 // handle.
1234 //
1235 // Returns the process handle via |process_out| on success, giving
1236 // ownership to the caller.  On failure, the return value doesn't
1237 // distinguish failure to send the first or second message from
1238 // failure to start the process, so on failure the loader-service
1239 // handle might or might not have been cleared and the handles to
1240 // transfer might or might not have been cleared.
launchpad_start(launchpad_t * lp,zx_handle_t * process_out)1241 static zx_status_t launchpad_start(launchpad_t* lp, zx_handle_t* process_out) {
1242     if (lp->error)
1243         return lp->error;
1244 
1245     launchpad_start_data_t data;
1246     zx_status_t status = prepare_start(lp, &data);
1247     if (status != ZX_OK)
1248         return status;
1249 
1250     status = zx_process_start(data.process, data.thread, data.entry, data.sp,
1251                               data.bootstrap, data.vdso_base);
1252 
1253     zx_handle_close(data.thread);
1254     zx_handle_close(data.root_vmar);
1255 
1256     if (status != ZX_OK) {
1257         zx_handle_close(data.process);
1258         return lp_error(lp, status, "zx_process_start() failed");
1259     }
1260 
1261     *process_out = data.process;
1262     return ZX_OK;
1263 }
1264 
launchpad_go(launchpad_t * lp,zx_handle_t * proc,const char ** errmsg)1265 zx_status_t launchpad_go(launchpad_t* lp, zx_handle_t* proc, const char** errmsg) {
1266     zx_handle_t h = ZX_HANDLE_INVALID;
1267     zx_status_t status = launchpad_start(lp, &h);
1268     if (errmsg)
1269         *errmsg = lp->errmsg;
1270     if (status == ZX_OK) {
1271         if (proc) {
1272             *proc = h;
1273         } else {
1274             zx_handle_close(h);
1275         }
1276     }
1277     launchpad_destroy(lp);
1278     return status;
1279 }
1280 
launchpad_ready_set(launchpad_t * lp,launchpad_start_data_t * data,const char ** errmsg)1281 zx_status_t launchpad_ready_set(launchpad_t* lp,
1282                                 launchpad_start_data_t* data,
1283                                 const char** errmsg) {
1284     zx_status_t status = prepare_start(lp, data);
1285     if (errmsg)
1286         *errmsg = lp->errmsg;
1287     launchpad_destroy(lp);
1288     return status;
1289 }
1290 
launchpad_file_load_with_vdso(launchpad_t * lp,zx_handle_t vmo)1291 static zx_status_t launchpad_file_load_with_vdso(launchpad_t* lp, zx_handle_t vmo) {
1292     launchpad_file_load(lp, vmo);
1293     launchpad_load_vdso(lp, ZX_HANDLE_INVALID);
1294     return launchpad_add_vdso_vmo(lp);
1295 }
1296 
launchpad_load_from_file(launchpad_t * lp,const char * path)1297 zx_status_t launchpad_load_from_file(launchpad_t* lp, const char* path) {
1298     zx_handle_t vmo;
1299     zx_status_t status = launchpad_vmo_from_file(path, &vmo);
1300     if (status == ZX_OK) {
1301         return launchpad_file_load_with_vdso(lp, vmo);
1302     } else {
1303         return lp_error(lp, status, "launchpad_vmo_from_file failure");
1304     }
1305 }
1306 
launchpad_load_from_fd(launchpad_t * lp,int fd)1307 zx_status_t launchpad_load_from_fd(launchpad_t* lp, int fd) {
1308     zx_handle_t vmo;
1309     zx_status_t status = fdio_get_vmo_clone(fd, &vmo);
1310     if (status == ZX_OK) {
1311         return launchpad_file_load_with_vdso(lp, vmo);
1312     } else {
1313         return status;
1314     }
1315 }
1316 
launchpad_load_from_vmo(launchpad_t * lp,zx_handle_t vmo)1317 zx_status_t launchpad_load_from_vmo(launchpad_t* lp, zx_handle_t vmo) {
1318     return launchpad_file_load_with_vdso(lp, vmo);
1319 }
1320