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/uaccess.h>
31 #include <ipxe/image.h>
32 #include <ipxe/zlib.h>
33 
34 /** @file
35  *
36  * zlib compressed images
37  *
38  */
39 
40 /**
41  * Extract compressed data to image
42  *
43  * @v format Compression format code
44  * @v in Compressed input chunk
45  * @v extracted Extracted image
46  * @ret rc Return status code
47  */
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  /* (Re)initialise input chunk */
68  in->offset = 0;
69 
70  /* Initialise output chunk */
71  deflate_chunk_init ( &out, extracted->data, 0, extracted->len );
72 
73  /* Decompress data */
74  if ( ( rc = deflate_inflate ( deflate, in, &out ) ) != 0 ) {
75  DBGC ( extracted, "ZLIB %p could not decompress: %s\n",
76  extracted, strerror ( rc ) );
77  goto err_inflate;
78  }
79 
80  /* Check that decompression is valid */
81  if ( ! deflate_finished ( deflate ) ) {
82  DBGC ( extracted, "ZLIB %p decompression incomplete\n",
83  extracted );
84  rc = -EINVAL;
85  goto err_unfinished;
86  }
87 
88  /* Finish if output image size was correct */
89  if ( out.offset == extracted->len )
90  break;
91 
92  /* Otherwise, resize output image and retry */
93  if ( ( rc = image_set_len ( extracted, out.offset ) ) != 0 ) {
94  DBGC ( extracted, "ZLIB %p could not resize: %s\n",
95  extracted, strerror ( rc ) );
96  goto err_set_size;
97  }
98  }
99 
100  /* Success */
101  rc = 0;
102 
103  err_set_size:
104  err_unfinished:
105  err_inflate:
106  free ( deflate );
107  err_alloc:
108  return rc;
109 }
110 
111 /**
112  * Extract zlib image
113  *
114  * @v image Image
115  * @v extracted Extracted image
116  * @ret rc Return status code
117  */
118 static int zlib_extract ( struct image *image, struct image *extracted ) {
119  struct deflate_chunk in;
120  int rc;
121 
122  /* Initialise input chunk */
123  deflate_chunk_init ( &in, image->data, 0, image->len );
124 
125  /* Decompress image */
126  if ( ( rc = zlib_deflate ( DEFLATE_ZLIB, &in, extracted ) ) != 0 )
127  return rc;
128 
129  return 0;
130 }
131 
132 /**
133  * Probe zlib image
134  *
135  * @v image zlib image
136  * @ret rc Return status code
137  */
138 static int zlib_probe ( struct image *image ) {
139  union zlib_magic magic;
140 
141  /* Sanity check */
142  if ( image->len < sizeof ( magic ) ) {
143  DBGC ( image, "ZLIB %p image too short\n", image );
144  return -ENOEXEC;
145  }
146 
147  /* Check magic header */
148  copy_from_user ( &magic, image->data, 0, sizeof ( magic ) );
149  if ( ! zlib_magic_is_valid ( &magic ) ) {
150  DBGC ( image, "ZLIB %p invalid magic data\n", image );
151  return -ENOEXEC;
152  }
153 
154  return 0;
155 }
156 
157 /** zlib image type */
158 struct image_type zlib_image_type __image_type ( PROBE_NORMAL ) = {
159  .name = "zlib",
160  .probe = zlib_probe,
161  .extract = zlib_extract,
162  .exec = image_extract_exec,
163 };
int deflate_inflate(struct deflate *deflate, struct deflate_chunk *in, struct deflate_chunk *out)
Inflate compressed data.
Definition: deflate.c:492
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
__be32 in[4]
Definition: CIB_PRM.h:35
struct image_type zlib_image_type __image_type(PROBE_NORMAL)
zlib image type
Error codes.
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image type.
Definition: image.h:76
uint32_t magic
Magic signature.
Definition: fdt.h:12
#define PROBE_NORMAL
Normal image probe priority.
Definition: image.h:137
An executable image.
Definition: image.h:24
Access to external ("user") memory.
__be32 out[4]
Definition: CIB_PRM.h:36
char * name
Name of this image type.
Definition: image.h:78
static int zlib_extract(struct image *image, struct image *extracted)
Extract zlib image.
Definition: zlib.c:118
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ENOMEM
Not enough space.
Definition: errno.h:534
A chunk of data.
Definition: deflate.h:241
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
Definition: deflate.c:999
Assertions.
zlib compressed images
Executable images.
static int deflate_finished(struct deflate *deflate)
Check if decompression has finished.
Definition: deflate.h:273
int zlib_deflate(enum deflate_format format, struct deflate_chunk *in, struct image *extracted)
Extract compressed data to image.
Definition: zlib.c:48
ZLIB header and footer.
Definition: deflate.h:21
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:17
zlib magic header
Definition: zlib.h:18
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
size_t len
Length of raw file image.
Definition: image.h:43
static int zlib_magic_is_valid(union zlib_magic *magic)
Check that zlib magic header is valid.
Definition: zlib.h:31
int image_set_len(struct image *image, size_t len)
Set image length.
Definition: image.c:201
static int zlib_probe(struct image *image)
Probe zlib image.
Definition: zlib.c:138
DEFLATE decompression algorithm.
int const char * format
Definition: xfer.h:104
int image_extract_exec(struct image *image)
Extract and execute image.
Definition: archive.c:110
Decompressor.
Definition: deflate.h:156