fdt.c (c1144d29f405ce1f4e6ede6482beb3d0d09750c6) fdt.c (f858927fd6ce394a7f431153d44ad0a09e8f49a1)
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or

--- 41 unchanged lines hidden (view full) ---

50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or

--- 41 unchanged lines hidden (view full) ---

50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58int fdt_check_header(const void *fdt)
58/*
59 * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks
60 * that the given buffer contains what appears to be a flattened
61 * device tree with sane information in its header.
62 */
63int fdt_ro_probe_(const void *fdt)
59{
60 if (fdt_magic(fdt) == FDT_MAGIC) {
61 /* Complete tree */
62 if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
63 return -FDT_ERR_BADVERSION;
64 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
65 return -FDT_ERR_BADVERSION;
66 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
67 /* Unfinished sequential-write blob */
68 if (fdt_size_dt_struct(fdt) == 0)
69 return -FDT_ERR_BADSTATE;
70 } else {
71 return -FDT_ERR_BADMAGIC;
72 }
73
74 return 0;
75}
76
64{
65 if (fdt_magic(fdt) == FDT_MAGIC) {
66 /* Complete tree */
67 if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
68 return -FDT_ERR_BADVERSION;
69 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
70 return -FDT_ERR_BADVERSION;
71 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
72 /* Unfinished sequential-write blob */
73 if (fdt_size_dt_struct(fdt) == 0)
74 return -FDT_ERR_BADSTATE;
75 } else {
76 return -FDT_ERR_BADMAGIC;
77 }
78
79 return 0;
80}
81
82static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)
83{
84 return (off >= hdrsize) && (off <= totalsize);
85}
86
87static int check_block_(uint32_t hdrsize, uint32_t totalsize,
88 uint32_t base, uint32_t size)
89{
90 if (!check_off_(hdrsize, totalsize, base))
91 return 0; /* block start out of bounds */
92 if ((base + size) < base)
93 return 0; /* overflow */
94 if (!check_off_(hdrsize, totalsize, base + size))
95 return 0; /* block end out of bounds */
96 return 1;
97}
98
99size_t fdt_header_size_(uint32_t version)
100{
101 if (version <= 1)
102 return FDT_V1_SIZE;
103 else if (version <= 2)
104 return FDT_V2_SIZE;
105 else if (version <= 3)
106 return FDT_V3_SIZE;
107 else if (version <= 16)
108 return FDT_V16_SIZE;
109 else
110 return FDT_V17_SIZE;
111}
112
113int fdt_check_header(const void *fdt)
114{
115 size_t hdrsize;
116
117 if (fdt_magic(fdt) != FDT_MAGIC)
118 return -FDT_ERR_BADMAGIC;
119 hdrsize = fdt_header_size(fdt);
120 if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
121 || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
122 return -FDT_ERR_BADVERSION;
123 if (fdt_version(fdt) < fdt_last_comp_version(fdt))
124 return -FDT_ERR_BADVERSION;
125
126 if ((fdt_totalsize(fdt) < hdrsize)
127 || (fdt_totalsize(fdt) > INT_MAX))
128 return -FDT_ERR_TRUNCATED;
129
130 /* Bounds check memrsv block */
131 if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
132 return -FDT_ERR_TRUNCATED;
133
134 /* Bounds check structure block */
135 if (fdt_version(fdt) < 17) {
136 if (!check_off_(hdrsize, fdt_totalsize(fdt),
137 fdt_off_dt_struct(fdt)))
138 return -FDT_ERR_TRUNCATED;
139 } else {
140 if (!check_block_(hdrsize, fdt_totalsize(fdt),
141 fdt_off_dt_struct(fdt),
142 fdt_size_dt_struct(fdt)))
143 return -FDT_ERR_TRUNCATED;
144 }
145
146 /* Bounds check strings block */
147 if (!check_block_(hdrsize, fdt_totalsize(fdt),
148 fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
149 return -FDT_ERR_TRUNCATED;
150
151 return 0;
152}
153
77const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
78{
79 unsigned absoffset = offset + fdt_off_dt_struct(fdt);
80
81 if ((absoffset < offset)
82 || ((absoffset + len) < absoffset)
83 || (absoffset + len) > fdt_totalsize(fdt))
84 return NULL;

--- 154 unchanged lines hidden (view full) ---

239 for (p = strtab; p <= last; p++)
240 if (memcmp(p, s, len) == 0)
241 return p;
242 return NULL;
243}
244
245int fdt_move(const void *fdt, void *buf, int bufsize)
246{
154const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
155{
156 unsigned absoffset = offset + fdt_off_dt_struct(fdt);
157
158 if ((absoffset < offset)
159 || ((absoffset + len) < absoffset)
160 || (absoffset + len) > fdt_totalsize(fdt))
161 return NULL;

--- 154 unchanged lines hidden (view full) ---

316 for (p = strtab; p <= last; p++)
317 if (memcmp(p, s, len) == 0)
318 return p;
319 return NULL;
320}
321
322int fdt_move(const void *fdt, void *buf, int bufsize)
323{
247 FDT_CHECK_HEADER(fdt);
324 FDT_RO_PROBE(fdt);
248
249 if (fdt_totalsize(fdt) > bufsize)
250 return -FDT_ERR_NOSPACE;
251
252 memmove(buf, fdt, fdt_totalsize(fdt));
253 return 0;
254}
325
326 if (fdt_totalsize(fdt) > bufsize)
327 return -FDT_ERR_NOSPACE;
328
329 memmove(buf, fdt, fdt_totalsize(fdt));
330 return 0;
331}