Changeset d091007 in mainline for boot/generic/src/gzip.c


Ignore:
Timestamp:
2021-06-04T16:58:15Z (3 years ago)
Author:
Martin Decky <martin@…>
Branches:
master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3c8c580
Parents:
da15002
Message:

Detect a compressed component by GZIP signature, not file extension

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/generic/src/gzip.c

    rda15002 rd091007  
    6363} __attribute__((packed)) gzip_footer_t;
    6464
    65 size_t gzip_size(const void *src, size_t srclen)
     65/** Check GZIP signature
     66 *
     67 * Checks whether the source buffer start with a GZIP signature.
     68 *
     69 * @param[in] src    Source data buffer.
     70 * @param[in] srclen Source buffer size (bytes).
     71 *
     72 * @return True if GZIP signature found.
     73 * @return False if no GZIP signature found.
     74 *
     75 */
     76bool gzip_check(const void *src, size_t srclen)
    6677{
     78        if ((srclen < (sizeof(gzip_header_t) + sizeof(gzip_footer_t))))
     79                return false;
     80
    6781        gzip_header_t header;
    68         gzip_footer_t footer;
    69 
    70         if ((srclen < sizeof(header)) || (srclen < sizeof(footer)))
    71                 return 0;
    72 
    7382        memcpy(&header, src, sizeof(header));
    74         memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
    7583
    7684        if ((header.id1 != GZIP_ID1) ||
     
    7886            (header.method != GZIP_METHOD_DEFLATE) ||
    7987            ((header.flags & (~GZIP_FLAGS_MASK)) != 0))
     88                return false;
     89
     90        return true;
     91}
     92
     93/** Get uncompressed size
     94 *
     95 * Note that the uncompressed size is read from the GZIP footer
     96 * (and not calculated by acutally decompressing the GZip archive).
     97 * Thus the source of the GZip archive needs to be trusted.
     98 *
     99 * @param[in]  src    Source data buffer.
     100 * @param[out] srclen Source buffer size (bytes).
     101 *
     102 * @return Uncompressed size.
     103 *
     104 */
     105size_t gzip_size(const void *src, size_t srclen)
     106{
     107        if (!gzip_check(src, srclen))
    80108                return 0;
     109
     110        gzip_footer_t footer;
     111        memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
    81112
    82113        return uint32_t_le2host(footer.size);
     
    85116/** Expand GZIP compressed data
    86117 *
    87  * The routine allocates the output buffer based
    88  * on the size encoded in the input stream. This
     118 * The routine compares the output buffer size with
     119 * the size encoded in the input stream. This
    89120 * effectively limits the size of the uncompressed
    90121 * data to 4 GiB (expanding input streams that actually
     
    108139int gzip_expand(const void *src, size_t srclen, void *dest, size_t destlen)
    109140{
     141        if (!gzip_check(src, srclen))
     142                return EINVAL;
     143
     144        /* Decode header and footer */
     145
    110146        gzip_header_t header;
     147        memcpy(&header, src, sizeof(header));
     148
    111149        gzip_footer_t footer;
    112 
    113         if ((srclen < sizeof(header)) || (srclen < sizeof(footer)))
    114                 return EINVAL;
    115 
    116         /* Decode header and footer */
    117 
    118         memcpy(&header, src, sizeof(header));
    119150        memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
    120 
    121         if ((header.id1 != GZIP_ID1) ||
    122             (header.id2 != GZIP_ID2) ||
    123             (header.method != GZIP_METHOD_DEFLATE) ||
    124             ((header.flags & (~GZIP_FLAGS_MASK)) != 0))
    125                 return EINVAL;
    126151
    127152        if (destlen != uint32_t_le2host(footer.size))
Note: See TracChangeset for help on using the changeset viewer.