iPXE
gzip.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdlib.h>
28#include <string.h>
29#include <errno.h>
30#include <assert.h>
31#include <ipxe/deflate.h>
32#include <ipxe/image.h>
33#include <ipxe/zlib.h>
34#include <ipxe/gzip.h>
35
36/** @file
37 *
38 * gzip compressed images
39 *
40 */
41
42/**
43 * Extract gzip image
44 *
45 * @v image Image
46 * @v extracted Extracted image
47 * @ret rc Return status code
48 */
49static int gzip_extract ( struct image *image, struct image *extracted ) {
50 const struct gzip_header *header;
51 const struct gzip_extra_header *extra;
52 const struct gzip_crc_header *crc;
53 const struct gzip_footer *footer;
54 const void *data;
55 size_t extra_len;
56 size_t string_len;
57 size_t len;
58 unsigned int strings;
59 int rc;
60
61 /* Sanity check */
62 assert ( image->len >= ( sizeof ( *header ) + sizeof ( *footer ) ) );
63 data = image->data;
64 len = image->len;
65
66 /* Extract footer */
67 assert ( len >= sizeof ( *footer ) );
68 len -= sizeof ( *footer );
69 footer = ( data + len );
70
71 /* Extract fixed header */
72 assert ( len >= sizeof ( *header ) );
73 header = data;
74 data += sizeof ( *header );
75 len -= sizeof ( *header );
76
77 /* Skip extra header, if present */
78 if ( header->flags & GZIP_FL_EXTRA ) {
79 if ( len < sizeof ( *extra ) ) {
80 DBGC ( image, "GZIP %s overlength extra header\n",
81 image->name );
82 return -EINVAL;
83 }
84 extra = data;
85 data += sizeof ( *extra );
86 len -= sizeof ( *extra );
87 extra_len = le16_to_cpu ( extra->len );
88 if ( len < extra_len ) {
89 DBGC ( image, "GZIP %s overlength extra header\n",
90 image->name );
91 return -EINVAL;
92 }
93 data += extra_len;
94 len -= extra_len;
95 }
96
97 /* Skip name and/or comment, if present */
98 strings = 0;
99 if ( header->flags & GZIP_FL_NAME )
100 strings++;
101 if ( header->flags & GZIP_FL_COMMENT )
102 strings++;
103 while ( strings-- ) {
104 string_len = strnlen ( data, len );
105 if ( string_len == len ) {
106 DBGC ( image, "GZIP %s overlength name/comment\n",
107 image->name );
108 return -EINVAL;
109 }
110 data += ( string_len + 1 /* NUL */ );
111 len -= ( string_len + 1 /* NUL */ );
112 }
113
114 /* Skip CRC, if present */
115 if ( header->flags & GZIP_FL_HCRC ) {
116 if ( len < sizeof ( *crc ) ) {
117 DBGC ( image, "GZIP %s overlength CRC header\n",
118 image->name );
119 return -EINVAL;
120 }
121 data += sizeof ( *crc );
122 len -= sizeof ( *crc );
123 }
124
125 /* Presize extracted image */
126 if ( ( rc = image_set_len ( extracted,
127 le32_to_cpu ( footer->len ) ) ) != 0 ) {
128 DBGC ( image, "GZIP %s could not presize: %s\n",
129 image->name, strerror ( rc ) );
130 return rc;
131 }
132
133 /* Decompress image (expanding if necessary) */
134 if ( ( rc = zlib_deflate ( DEFLATE_RAW, data, len,
135 extracted ) ) != 0 ) {
136 DBGC ( image, "GZIP %s could not decompress: %s\n",
137 image->name, strerror ( rc ) );
138 return rc;
139 }
140
141 return 0;
142}
143
144/**
145 * Probe gzip image
146 *
147 * @v image gzip image
148 * @ret rc Return status code
149 */
150static int gzip_probe ( struct image *image ) {
151 const struct gzip_header *header;
152 const struct gzip_footer *footer;
153
154 /* Sanity check */
155 if ( image->len < ( sizeof ( *header ) + sizeof ( *footer ) ) ) {
156 DBGC ( image, "GZIP %s image too short\n", image->name );
157 return -ENOEXEC;
158 }
159 header = image->data;
160
161 /* Check magic header */
162 if ( header->magic != cpu_to_be16 ( GZIP_MAGIC ) ) {
163 DBGC ( image, "GZIP %s invalid magic\n", image->name );
164 return -ENOEXEC;
165 }
166
167 return 0;
168}
169
170/** gzip image type */
171struct image_type gzip_image_type __image_type ( PROBE_NORMAL ) = {
172 .name = "gzip",
173 .probe = gzip_probe,
174 .extract = gzip_extract,
175 .exec = image_extract_exec,
176};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int image_extract_exec(struct image *image)
Extract and execute image.
Definition archive.c:108
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
DEFLATE decompression algorithm.
@ DEFLATE_RAW
Raw DEFLATE data (no header or footer)
Definition deflate.h:19
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
struct ena_llq_option header
Header locations.
Definition ena.h:5
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOEXEC
Exec format error.
Definition errno.h:520
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
static int gzip_extract(struct image *image, struct image *extracted)
Extract gzip image.
Definition gzip.c:49
static int gzip_probe(struct image *image)
Probe gzip image.
Definition gzip.c:150
gzip compressed images
#define GZIP_FL_EXTRA
Extra header is present.
Definition gzip.h:42
#define GZIP_FL_HCRC
CRC header is present.
Definition gzip.h:39
#define GZIP_FL_COMMENT
File comment is present.
Definition gzip.h:48
#define GZIP_FL_NAME
File name is present.
Definition gzip.h:45
#define GZIP_MAGIC
Magic ID.
Definition gzip.h:33
int image_set_len(struct image *image, size_t len)
Set image length.
Definition image.c:245
Executable images.
#define PROBE_NORMAL
Normal image probe priority.
Definition image.h:156
#define __image_type(probe_order)
An executable image type.
Definition image.h:170
#define cpu_to_be16(value)
Definition byteswap.h:110
#define le16_to_cpu(value)
Definition byteswap.h:113
#define le32_to_cpu(value)
Definition byteswap.h:114
uint8_t extra
Signature extra byte.
Definition smbios.h:6
String functions.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition string.c:256
gzip CRC header
Definition gzip.h:57
uint16_t crc
CRC-16.
Definition gzip.h:59
gzip extra header
Definition gzip.h:51
gzip header
Definition gzip.h:17
An executable image type.
Definition image.h:95
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56
int zlib_deflate(enum deflate_format format, const void *data, size_t len, struct image *extracted)
Extract compressed data to image.
Definition zlib.c:49
zlib compressed images