diff options
Diffstat (limited to 'scripts/dtc/libfdt/fdt.c')
-rw-r--r-- | scripts/dtc/libfdt/fdt.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 2acaec5923ae..e56833ae9b6f 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c | |||
@@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt) | |||
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | const void *fdt_offset_ptr(const void *fdt, int offset, int len) | 77 | const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) |
78 | { | 78 | { |
79 | const char *p; | 79 | const char *p; |
80 | 80 | ||
@@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len) | |||
90 | return p; | 90 | return p; |
91 | } | 91 | } |
92 | 92 | ||
93 | uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) | 93 | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) |
94 | { | 94 | { |
95 | const uint32_t *tagp, *lenp; | 95 | const uint32_t *tagp, *lenp; |
96 | uint32_t tag; | 96 | uint32_t tag; |
97 | int offset = startoffset; | ||
97 | const char *p; | 98 | const char *p; |
98 | 99 | ||
99 | if (offset % FDT_TAGSIZE) | 100 | *nextoffset = -FDT_ERR_TRUNCATED; |
100 | return -1; | ||
101 | |||
102 | tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); | 101 | tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); |
103 | if (! tagp) | 102 | if (!tagp) |
104 | return FDT_END; /* premature end */ | 103 | return FDT_END; /* premature end */ |
105 | tag = fdt32_to_cpu(*tagp); | 104 | tag = fdt32_to_cpu(*tagp); |
106 | offset += FDT_TAGSIZE; | 105 | offset += FDT_TAGSIZE; |
107 | 106 | ||
107 | *nextoffset = -FDT_ERR_BADSTRUCTURE; | ||
108 | switch (tag) { | 108 | switch (tag) { |
109 | case FDT_BEGIN_NODE: | 109 | case FDT_BEGIN_NODE: |
110 | /* skip name */ | 110 | /* skip name */ |
111 | do { | 111 | do { |
112 | p = fdt_offset_ptr(fdt, offset++, 1); | 112 | p = fdt_offset_ptr(fdt, offset++, 1); |
113 | } while (p && (*p != '\0')); | 113 | } while (p && (*p != '\0')); |
114 | if (! p) | 114 | if (!p) |
115 | return FDT_END; | 115 | return FDT_END; /* premature end */ |
116 | break; | 116 | break; |
117 | |||
117 | case FDT_PROP: | 118 | case FDT_PROP: |
118 | lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); | 119 | lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); |
119 | if (! lenp) | 120 | if (!lenp) |
120 | return FDT_END; | 121 | return FDT_END; /* premature end */ |
121 | /* skip name offset, length and value */ | 122 | /* skip-name offset, length and value */ |
122 | offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); | 123 | offset += sizeof(struct fdt_property) - FDT_TAGSIZE |
124 | + fdt32_to_cpu(*lenp); | ||
125 | break; | ||
126 | |||
127 | case FDT_END: | ||
128 | case FDT_END_NODE: | ||
129 | case FDT_NOP: | ||
123 | break; | 130 | break; |
131 | |||
132 | default: | ||
133 | return FDT_END; | ||
124 | } | 134 | } |
125 | 135 | ||
126 | if (nextoffset) | 136 | if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) |
127 | *nextoffset = FDT_TAGALIGN(offset); | 137 | return FDT_END; /* premature end */ |
128 | 138 | ||
139 | *nextoffset = FDT_TAGALIGN(offset); | ||
129 | return tag; | 140 | return tag; |
130 | } | 141 | } |
131 | 142 | ||
@@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset) | |||
138 | return offset; | 149 | return offset; |
139 | } | 150 | } |
140 | 151 | ||
152 | int _fdt_check_prop_offset(const void *fdt, int offset) | ||
153 | { | ||
154 | if ((offset < 0) || (offset % FDT_TAGSIZE) | ||
155 | || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) | ||
156 | return -FDT_ERR_BADOFFSET; | ||
157 | |||
158 | return offset; | ||
159 | } | ||
160 | |||
141 | int fdt_next_node(const void *fdt, int offset, int *depth) | 161 | int fdt_next_node(const void *fdt, int offset, int *depth) |
142 | { | 162 | { |
143 | int nextoffset = 0; | 163 | int nextoffset = 0; |
@@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth) | |||
162 | break; | 182 | break; |
163 | 183 | ||
164 | case FDT_END_NODE: | 184 | case FDT_END_NODE: |
165 | if (depth) | 185 | if (depth && ((--(*depth)) < 0)) |
166 | (*depth)--; | 186 | return nextoffset; |
167 | break; | 187 | break; |
168 | 188 | ||
169 | case FDT_END: | 189 | case FDT_END: |
170 | return -FDT_ERR_NOTFOUND; | 190 | if ((nextoffset >= 0) |
171 | 191 | || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) | |
172 | default: | 192 | return -FDT_ERR_NOTFOUND; |
173 | return -FDT_ERR_BADSTRUCTURE; | 193 | else |
194 | return nextoffset; | ||
174 | } | 195 | } |
175 | } while (tag != FDT_BEGIN_NODE); | 196 | } while (tag != FDT_BEGIN_NODE); |
176 | 197 | ||