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 <lib/bootfs/parser.h>
6
7 #include <inttypes.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include <lib/zx/vmar.h>
13 #include <lib/zx/vmo.h>
14 #include <zircon/boot/bootdata.h>
15 #include <zircon/process.h>
16 #include <zircon/syscalls.h>
17 #include <zircon/types.h>
18
19 namespace bootfs {
20
~Parser()21 Parser::~Parser() {
22 if (dir_) {
23 uintptr_t addr = reinterpret_cast<uintptr_t>(dir_) - sizeof(bootfs_header_t);
24 zx::vmar::root_self()->unmap(addr, MappingSize());
25 }
26 }
27
Init(zx::unowned_vmo vmo)28 zx_status_t Parser::Init(zx::unowned_vmo vmo) {
29 if (dir_ != nullptr) {
30 return ZX_ERR_BAD_STATE;
31 }
32
33 bootfs_header_t hdr;
34 zx_status_t r = vmo->read(&hdr, 0, sizeof(hdr));
35 if (r != ZX_OK) {
36 printf("Parser::Init: couldn't read boot_data - %d\n", r);
37 return r;
38 }
39 if (hdr.magic != BOOTFS_MAGIC) {
40 printf("Parser::Init: incorrect bootdata header: %x\n", hdr.magic);
41 return ZX_ERR_IO;
42 }
43 zx_vaddr_t addr = 0;
44 if ((r = zx::vmar::root_self()->map(0, *vmo, 0, sizeof(hdr) + hdr.dirsize,
45 ZX_VM_PERM_READ, &addr)) != ZX_OK) {
46 printf("Parser::Init: couldn't map directory: %d\n", r);
47 return r;
48 }
49 dirsize_ = hdr.dirsize;
50 dir_ = reinterpret_cast<char*>(addr) + sizeof(hdr);
51 return ZX_OK;
52 }
53
Parse(Callback callback)54 zx_status_t Parser::Parse(Callback callback) {
55 if (dir_ == nullptr) {
56 return ZX_ERR_BAD_STATE;
57 }
58 size_t avail = dirsize_;
59 auto* p = static_cast<char*>(dir_);
60 zx_status_t r;
61 while (avail > sizeof(bootfs_entry_t)) {
62 auto e = reinterpret_cast<bootfs_entry_t*>(p);
63 size_t sz = BOOTFS_RECSIZE(e);
64 if ((e->name_len < 1) || (e->name_len > BOOTFS_MAX_NAME_LEN) ||
65 (e->name[e->name_len - 1] != 0) || (sz > avail)) {
66 printf("bootfs: bogus entry!\n");
67 return ZX_ERR_IO;
68 }
69 if ((r = callback(e)) != ZX_OK) {
70 return r;
71 }
72 p += sz;
73 avail -= sz;
74 }
75 return ZX_OK;
76 }
77
78 } // namespace bootfs
79