iPXE
zlib.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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <ipxe/deflate.h>
30 #include <ipxe/image.h>
31 #include <ipxe/zlib.h>
32 
33 /** @file
34  *
35  * zlib compressed images
36  *
37  */
38 
39 /**
40  * Extract compressed data to image
41  *
42  * @v format Compression format code
43  * @v data Compressed input data
44  * @v len Length of compressed input data
45  * @v extracted Extracted image
46  * @ret rc Return status code
47  */
48 int zlib_deflate ( enum deflate_format format, const void *data, size_t len,
49  struct image *extracted ) {
50  struct deflate *deflate;
51  struct deflate_chunk out;
52  int rc;
53 
54  /* Allocate and initialise decompressor */
55  deflate = zalloc ( sizeof ( *deflate ) );
56  if ( ! deflate ) {
57  rc = -ENOMEM;
58  goto err_alloc;
59  }
60 
61  /* Decompress data, (re)allocating if necessary */
62  while ( 1 ) {
63 
64  /* (Re)initialise decompressor */
66 
67  /* Initialise output chunk */
68  deflate_chunk_init ( &out, extracted->rwdata, 0,
69  extracted->len );
70 
71  /* Decompress data */
72  if ( ( rc = deflate_inflate ( deflate, data, len,
73  &out ) ) != 0 ) {
74  DBGC ( extracted, "ZLIB %s could not decompress: %s\n",
75  extracted->name, strerror ( rc ) );
76  goto err_inflate;
77  }
78 
79  /* Check that decompression is valid */
80  if ( ! deflate_finished ( deflate ) ) {
81  DBGC ( extracted, "ZLIB %s decompression incomplete\n",
82  extracted->name );
83  rc = -EINVAL;
84  goto err_unfinished;
85  }
86 
87  /* Finish if output image size was correct */
88  if ( out.offset == extracted->len )
89  break;
90 
91  /* Otherwise, resize output image and retry */
92  if ( ( rc = image_set_len ( extracted, out.offset ) ) != 0 ) {
93  DBGC ( extracted, "ZLIB %s could not resize: %s\n",
94  extracted->name, strerror ( rc ) );
95  goto err_set_size;
96  }
97  }
98 
99  /* Success */
100  rc = 0;
101 
102  err_set_size:
103  err_unfinished:
104  err_inflate:
105  free ( deflate );
106  err_alloc:
107  return rc;
108 }
109 
110 /**
111  * Extract zlib image
112  *
113  * @v image Image
114  * @v extracted Extracted image
115  * @ret rc Return status code
116  */
117 static int zlib_extract ( struct image *image, struct image *extracted ) {
118  int rc;
119 
120  /* Decompress image */
121  if ( ( rc = zlib_deflate ( DEFLATE_ZLIB, image->data, image->len,
122  extracted ) ) != 0 )
123  return rc;
124 
125  return 0;
126 }
127 
128 /**
129  * Probe zlib image
130  *
131  * @v image zlib image
132  * @ret rc Return status code
133  */
134 static int zlib_probe ( struct image *image ) {
135  const union zlib_magic *magic;
136 
137  /* Sanity check */
138  if ( image->len < sizeof ( *magic ) ) {
139  DBGC ( image, "ZLIB %s image too short\n", image->name );
140  return -ENOEXEC;
141  }
142  magic = image->data;
143 
144  /* Check magic header */
145  if ( ! zlib_magic_is_valid ( magic ) ) {
146  DBGC ( image, "ZLIB %s invalid magic data\n", image->name );
147  return -ENOEXEC;
148  }
149 
150  return 0;
151 }
152 
153 /** zlib image type */
154 struct image_type zlib_image_type __image_type ( PROBE_NORMAL ) = {
155  .name = "zlib",
156  .probe = zlib_probe,
157  .extract = zlib_extract,
158  .exec = image_extract_exec,
159 };
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct image_type zlib_image_type __image_type(PROBE_NORMAL)
zlib image type
Error codes.
const void * data
Read-only data.
Definition: image.h:50
uint16_t magic
Magic signature.
Definition: bzimage.h:6
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image type.
Definition: image.h:94
#define PROBE_NORMAL
Normal image probe priority.
Definition: image.h:155
An executable image.
Definition: image.h:23
__be32 out[4]
Definition: CIB_PRM.h:36
char * name
Name of this image type.
Definition: image.h:96
static int zlib_extract(struct image *image, struct image *extracted)
Extract zlib image.
Definition: zlib.c:117
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ENOMEM
Not enough space.
Definition: errno.h:534
A chunk of data.
Definition: deflate.h:245
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
Definition: deflate.c:991
Assertions.
zlib compressed images
Executable images.
static int deflate_finished(struct deflate *deflate)
Check if decompression has finished.
Definition: deflate.h:277
ring len
Length.
Definition: dwmac.h:231
static int zlib_magic_is_valid(const union zlib_magic *magic)
Check that zlib magic header is valid.
Definition: zlib.h:31
ZLIB header and footer.
Definition: deflate.h:20
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
deflate_format
Compression formats.
Definition: deflate.h:16
zlib magic header
Definition: zlib.h:18
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
size_t len
Length of raw file image.
Definition: image.h:55
int deflate_inflate(struct deflate *deflate, const void *data, size_t len, struct deflate_chunk *out)
Inflate compressed data.
Definition: deflate.c:483
int image_set_len(struct image *image, size_t len)
Set image length.
Definition: image.c:244
static int zlib_probe(struct image *image)
Probe zlib image.
Definition: zlib.c:134
void * rwdata
Writable data.
Definition: image.h:52
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int zlib_deflate(enum deflate_format format, const void *data, size_t len, struct image *extracted)
Extract compressed data to image.
Definition: zlib.c:48
DEFLATE decompression algorithm.
int const char * format
Definition: xfer.h:104
char * name
Name.
Definition: image.h:37
int image_extract_exec(struct image *image)
Extract and execute image.
Definition: archive.c:107
Decompressor.
Definition: deflate.h:155