.. | .. |
---|
18 | 18 | struct ihex_binrec { |
---|
19 | 19 | __be32 addr; |
---|
20 | 20 | __be16 len; |
---|
21 | | - uint8_t data[0]; |
---|
| 21 | + uint8_t data[]; |
---|
22 | 22 | } __attribute__((packed)); |
---|
| 23 | + |
---|
| 24 | +static inline uint16_t ihex_binrec_size(const struct ihex_binrec *p) |
---|
| 25 | +{ |
---|
| 26 | + return be16_to_cpu(p->len) + sizeof(*p); |
---|
| 27 | +} |
---|
23 | 28 | |
---|
24 | 29 | /* Find the next record, taking into account the 4-byte alignment */ |
---|
25 | 30 | static inline const struct ihex_binrec * |
---|
| 31 | +__ihex_next_binrec(const struct ihex_binrec *rec) |
---|
| 32 | +{ |
---|
| 33 | + const void *p = rec; |
---|
| 34 | + |
---|
| 35 | + return p + ALIGN(ihex_binrec_size(rec), 4); |
---|
| 36 | +} |
---|
| 37 | + |
---|
| 38 | +static inline const struct ihex_binrec * |
---|
26 | 39 | ihex_next_binrec(const struct ihex_binrec *rec) |
---|
27 | 40 | { |
---|
28 | | - int next = ((be16_to_cpu(rec->len) + 5) & ~3) - 2; |
---|
29 | | - rec = (void *)&rec->data[next]; |
---|
| 41 | + rec = __ihex_next_binrec(rec); |
---|
30 | 42 | |
---|
31 | 43 | return be16_to_cpu(rec->len) ? rec : NULL; |
---|
32 | 44 | } |
---|
.. | .. |
---|
34 | 46 | /* Check that ihex_next_binrec() won't take us off the end of the image... */ |
---|
35 | 47 | static inline int ihex_validate_fw(const struct firmware *fw) |
---|
36 | 48 | { |
---|
37 | | - const struct ihex_binrec *rec; |
---|
38 | | - size_t ofs = 0; |
---|
| 49 | + const struct ihex_binrec *end, *rec; |
---|
39 | 50 | |
---|
40 | | - while (ofs <= fw->size - sizeof(*rec)) { |
---|
41 | | - rec = (void *)&fw->data[ofs]; |
---|
| 51 | + rec = (const void *)fw->data; |
---|
| 52 | + end = (const void *)&fw->data[fw->size - sizeof(*end)]; |
---|
42 | 53 | |
---|
| 54 | + for (; rec <= end; rec = __ihex_next_binrec(rec)) { |
---|
43 | 55 | /* Zero length marks end of records */ |
---|
44 | | - if (!be16_to_cpu(rec->len)) |
---|
| 56 | + if (rec == end && !be16_to_cpu(rec->len)) |
---|
45 | 57 | return 0; |
---|
46 | | - |
---|
47 | | - /* Point to next record... */ |
---|
48 | | - ofs += (sizeof(*rec) + be16_to_cpu(rec->len) + 3) & ~3; |
---|
49 | 58 | } |
---|
50 | 59 | return -EINVAL; |
---|
51 | 60 | } |
---|