1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/efi.h>
4 #include <linux/pe.h>
5 #include <asm/efi.h>
6 #include <asm/unaligned.h>
7 
8 #include "efistub.h"
9 
10 static unsigned char zboot_heap[SZ_256K] __aligned(64);
11 static unsigned long free_mem_ptr, free_mem_end_ptr;
12 
13 #define STATIC static
14 #if defined(CONFIG_KERNEL_GZIP)
15 #include "../../../../lib/decompress_inflate.c"
16 #elif defined(CONFIG_KERNEL_LZ4)
17 #include "../../../../lib/decompress_unlz4.c"
18 #elif defined(CONFIG_KERNEL_LZMA)
19 #include "../../../../lib/decompress_unlzma.c"
20 #elif defined(CONFIG_KERNEL_LZO)
21 #include "../../../../lib/decompress_unlzo.c"
22 #elif defined(CONFIG_KERNEL_XZ)
23 #undef memcpy
24 #define memcpy memcpy
25 #undef memmove
26 #define memmove memmove
27 #include "../../../../lib/decompress_unxz.c"
28 #elif defined(CONFIG_KERNEL_ZSTD)
29 #include "../../../../lib/decompress_unzstd.c"
30 #endif
31 
32 extern char efi_zboot_header[];
33 extern char _gzdata_start[], _gzdata_end[];
34 
35 static void error(char *x)
36 {
37 	efi_err("EFI decompressor: %s\n", x);
38 }
39 
40 static efi_status_t __efiapi
41 load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem,
42 	  bool boot_policy, unsigned long *bufsize, void *buffer)
43 {
44 	unsigned long compressed_size = _gzdata_end - _gzdata_start;
45 	struct efi_vendor_dev_path *vendor_dp;
46 	bool decompress = false;
47 	unsigned long size;
48 	int ret;
49 
50 	if (rem == NULL || bufsize == NULL)
51 		return EFI_INVALID_PARAMETER;
52 
53 	if (boot_policy)
54 		return EFI_UNSUPPORTED;
55 
56 	// Look for our vendor media device node in the remaining file path
57 	if (rem->type == EFI_DEV_MEDIA &&
58 	    rem->sub_type == EFI_DEV_MEDIA_VENDOR) {
59 		vendor_dp = container_of(rem, struct efi_vendor_dev_path, header);
60 		if (efi_guidcmp(vendor_dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID))
61 			return EFI_NOT_FOUND;
62 
63 		decompress = true;
64 		rem = (void *)(vendor_dp + 1);
65 	}
66 
67 	if (rem->type != EFI_DEV_END_PATH ||
68 	    rem->sub_type != EFI_DEV_END_ENTIRE)
69 		return EFI_NOT_FOUND;
70 
71 	// The uncompressed size of the payload is appended to the raw bit
72 	// stream, and may therefore appear misaligned in memory
73 	size = decompress ? get_unaligned_le32(_gzdata_end - 4)
74 			  : compressed_size;
75 	if (buffer == NULL || *bufsize < size) {
76 		*bufsize = size;
77 		return EFI_BUFFER_TOO_SMALL;
78 	}
79 
80 	if (decompress) {
81 		ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
82 				   buffer, size, NULL, error);
83 		if (ret	< 0) {
84 			error("Decompression failed");
85 			return EFI_DEVICE_ERROR;
86 		}
87 	} else {
88 		memcpy(buffer, _gzdata_start, compressed_size);
89 	}
90 
91 	return EFI_SUCCESS;
92 }
93 
94 // Return the length in bytes of the device path up to the first end node.
95 static int device_path_length(const efi_device_path_protocol_t *dp)
96 {
97 	int len = 0;
98 
99 	while (dp->type != EFI_DEV_END_PATH) {
100 		len += dp->length;
101 		dp = (void *)((u8 *)dp + dp->length);
102 	}
103 	return len;
104 }
105 
106 static void append_rel_offset_node(efi_device_path_protocol_t **dp,
107 				   unsigned long start, unsigned long end)
108 {
109 	struct efi_rel_offset_dev_path *rodp = (void *)*dp;
110 
111 	rodp->header.type	= EFI_DEV_MEDIA;
112 	rodp->header.sub_type	= EFI_DEV_MEDIA_REL_OFFSET;
113 	rodp->header.length	= sizeof(struct efi_rel_offset_dev_path);
114 	rodp->reserved		= 0;
115 	rodp->starting_offset	= start;
116 	rodp->ending_offset	= end;
117 
118 	*dp = (void *)(rodp + 1);
119 }
120 
121 static void append_ven_media_node(efi_device_path_protocol_t **dp,
122 				  efi_guid_t *guid)
123 {
124 	struct efi_vendor_dev_path *vmdp = (void *)*dp;
125 
126 	vmdp->header.type	= EFI_DEV_MEDIA;
127 	vmdp->header.sub_type	= EFI_DEV_MEDIA_VENDOR;
128 	vmdp->header.length	= sizeof(struct efi_vendor_dev_path);
129 	vmdp->vendorguid	= *guid;
130 
131 	*dp = (void *)(vmdp + 1);
132 }
133 
134 static void append_end_node(efi_device_path_protocol_t **dp)
135 {
136 	(*dp)->type		= EFI_DEV_END_PATH;
137 	(*dp)->sub_type		= EFI_DEV_END_ENTIRE;
138 	(*dp)->length		= sizeof(struct efi_generic_dev_path);
139 
140 	++*dp;
141 }
142 
143 asmlinkage efi_status_t __efiapi
144 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
145 {
146 	struct efi_mem_mapped_dev_path mmdp = {
147 		.header.type		= EFI_DEV_HW,
148 		.header.sub_type	= EFI_DEV_MEM_MAPPED,
149 		.header.length		= sizeof(struct efi_mem_mapped_dev_path)
150 	};
151 	efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp;
152 	efi_load_file2_protocol_t zboot_load_file2;
153 	efi_loaded_image_t *parent, *child;
154 	unsigned long exit_data_size;
155 	efi_handle_t child_handle;
156 	efi_handle_t zboot_handle;
157 	efi_char16_t *exit_data;
158 	efi_status_t status;
159 	void *dp_alloc;
160 	int dp_len;
161 
162 	WRITE_ONCE(efi_system_table, systab);
163 
164 	free_mem_ptr = (unsigned long)&zboot_heap;
165 	free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap);
166 
167 	exit_data = NULL;
168 	exit_data_size = 0;
169 
170 	status = efi_bs_call(handle_protocol, handle,
171 			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&parent);
172 	if (status != EFI_SUCCESS) {
173 		error("Failed to locate parent's loaded image protocol");
174 		return status;
175 	}
176 
177 	status = efi_bs_call(handle_protocol, handle,
178 			     &LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
179 			     (void **)&parent_dp);
180 	if (status != EFI_SUCCESS || parent_dp == NULL) {
181 		// Create a MemoryMapped() device path node to describe
182 		// the parent image if no device path was provided.
183 		mmdp.memory_type	= parent->image_code_type;
184 		mmdp.starting_addr	= (unsigned long)parent->image_base;
185 		mmdp.ending_addr	= (unsigned long)parent->image_base +
186 					  parent->image_size - 1;
187 		parent_dp = &mmdp.header;
188 		dp_len = sizeof(mmdp);
189 	} else {
190 		dp_len = device_path_length(parent_dp);
191 	}
192 
193 	// Allocate some pool memory for device path protocol data
194 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
195 			     2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) +
196 			          sizeof(struct efi_generic_dev_path)) +
197 			     sizeof(struct efi_vendor_dev_path),
198 			     (void **)&dp_alloc);
199 	if (status != EFI_SUCCESS) {
200 		error("Failed to allocate device path pool memory");
201 		return status;
202 	}
203 
204 	// Create a device path describing the compressed payload in this image
205 	// <...parent_dp...>/Offset(<start>, <end>)
206 	lf2_dp = memcpy(dp_alloc, parent_dp, dp_len);
207 	dpp = (void *)((u8 *)lf2_dp + dp_len);
208 	append_rel_offset_node(&dpp,
209 			       (unsigned long)(_gzdata_start - efi_zboot_header),
210 			       (unsigned long)(_gzdata_end - efi_zboot_header - 1));
211 	append_end_node(&dpp);
212 
213 	// Create a device path describing the decompressed payload in this image
214 	// <...parent_dp...>/Offset(<start>, <end>)/VenMedia(ZBOOT_MEDIA_GUID)
215 	dp_len += sizeof(struct efi_rel_offset_dev_path);
216 	li_dp = memcpy(dpp, lf2_dp, dp_len);
217 	dpp = (void *)((u8 *)li_dp + dp_len);
218 	append_ven_media_node(&dpp, &LINUX_EFI_ZBOOT_MEDIA_GUID);
219 	append_end_node(&dpp);
220 
221 	zboot_handle = NULL;
222 	zboot_load_file2.load_file = load_file;
223 	status = efi_bs_call(install_multiple_protocol_interfaces,
224 			     &zboot_handle,
225 			     &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp,
226 			     &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2,
227 			     NULL);
228 	if (status != EFI_SUCCESS) {
229 		error("Failed to install LoadFile2 protocol and device path");
230 		goto free_dpalloc;
231 	}
232 
233 	status = efi_bs_call(load_image, false, handle, li_dp, NULL, 0,
234 			     &child_handle);
235 	if (status != EFI_SUCCESS) {
236 		error("Failed to load image");
237 		goto uninstall_lf2;
238 	}
239 
240 	status = efi_bs_call(handle_protocol, child_handle,
241 			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&child);
242 	if (status != EFI_SUCCESS) {
243 		error("Failed to locate child's loaded image protocol");
244 		goto unload_image;
245 	}
246 
247 	// Copy the kernel command line
248 	child->load_options = parent->load_options;
249 	child->load_options_size = parent->load_options_size;
250 
251 	status = efi_bs_call(start_image, child_handle, &exit_data_size,
252 			     &exit_data);
253 	if (status != EFI_SUCCESS) {
254 		error("StartImage() returned with error:");
255 		if (exit_data_size > 0)
256 			efi_err("%ls\n", exit_data);
257 
258 		// If StartImage() returns EFI_SECURITY_VIOLATION, the image is
259 		// not unloaded so we need to do it by hand.
260 		if (status == EFI_SECURITY_VIOLATION)
261 unload_image:
262 			efi_bs_call(unload_image, child_handle);
263 	}
264 
265 uninstall_lf2:
266 	efi_bs_call(uninstall_multiple_protocol_interfaces,
267 		    zboot_handle,
268 		    &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp,
269 		    &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2,
270 		    NULL);
271 
272 free_dpalloc:
273 	efi_bs_call(free_pool, dp_alloc);
274 
275 	efi_bs_call(exit, handle, status, exit_data_size, exit_data);
276 
277 	// Free ExitData in case Exit() returned with a failure code,
278 	// but return the original status code.
279 	error("Exit() returned with failure code");
280 	if (exit_data != NULL)
281 		efi_bs_call(free_pool, exit_data);
282 	return status;
283 }
284