| .. | .. |
|---|
| 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 | } |
|---|