1347 lines · 33.3 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * kexec: kexec_file_load system call * * Copyright (C) 2014 Red Hat Inc. * Authors: *      Vivek Goyal <vgoyal@redhat.com> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/capability.h>#include <linux/mm.h>#include <linux/file.h>#include <linux/slab.h>#include <linux/kexec.h>#include <linux/memblock.h>#include <linux/mutex.h>#include <linux/list.h>#include <linux/fs.h>#include <linux/ima.h>#include <crypto/hash.h>#include <crypto/sha.h>#include <linux/elf.h>#include <linux/elfcore.h>#include <linux/kernel.h>#include <linux/syscalls.h>#include <linux/vmalloc.h>#include "kexec_internal.h" static int kexec_calculate_store_digests(struct kimage *image); /* * Currently this is the only default function that is exported as some * architectures need it to do additional handlings. * In the future, other default functions may be exported too if required. */int kexec_image_probe_default(struct kimage *image, void *buf,			      unsigned long buf_len){	const struct kexec_file_ops * const *fops;	int ret = -ENOEXEC; 	for (fops = &kexec_file_loaders[0]; *fops && (*fops)->probe; ++fops) {		ret = (*fops)->probe(buf, buf_len);		if (!ret) {			image->fops = *fops;			return ret;		}	} 	return ret;} /* Architectures can provide this probe function */int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,					 unsigned long buf_len){	return kexec_image_probe_default(image, buf, buf_len);} static void *kexec_image_load_default(struct kimage *image){	if (!image->fops || !image->fops->load)		return ERR_PTR(-ENOEXEC); 	return image->fops->load(image, image->kernel_buf,				 image->kernel_buf_len, image->initrd_buf,				 image->initrd_buf_len, image->cmdline_buf,				 image->cmdline_buf_len);} void * __weak arch_kexec_kernel_image_load(struct kimage *image){	return kexec_image_load_default(image);} int kexec_image_post_load_cleanup_default(struct kimage *image){	if (!image->fops || !image->fops->cleanup)		return 0; 	return image->fops->cleanup(image->image_loader_data);} int __weak arch_kimage_file_post_load_cleanup(struct kimage *image){	return kexec_image_post_load_cleanup_default(image);} #ifdef CONFIG_KEXEC_SIGstatic int kexec_image_verify_sig_default(struct kimage *image, void *buf,					  unsigned long buf_len){	if (!image->fops || !image->fops->verify_sig) {		pr_debug("kernel loader does not support signature verification.\n");		return -EKEYREJECTED;	} 	return image->fops->verify_sig(buf, buf_len);} int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf,					unsigned long buf_len){	return kexec_image_verify_sig_default(image, buf, buf_len);}#endif /* * arch_kexec_apply_relocations_add - apply relocations of type RELA * @pi:		Purgatory to be relocated. * @section:	Section relocations applying to. * @relsec:	Section containing RELAs. * @symtab:	Corresponding symtab. * * Return: 0 on success, negative errno on error. */int __weakarch_kexec_apply_relocations_add(struct purgatory_info *pi, Elf_Shdr *section,				 const Elf_Shdr *relsec, const Elf_Shdr *symtab){	pr_err("RELA relocation unsupported.\n");	return -ENOEXEC;} /* * arch_kexec_apply_relocations - apply relocations of type REL * @pi:		Purgatory to be relocated. * @section:	Section relocations applying to. * @relsec:	Section containing RELs. * @symtab:	Corresponding symtab. * * Return: 0 on success, negative errno on error. */int __weakarch_kexec_apply_relocations(struct purgatory_info *pi, Elf_Shdr *section,			     const Elf_Shdr *relsec, const Elf_Shdr *symtab){	pr_err("REL relocation unsupported.\n");	return -ENOEXEC;} /* * Free up memory used by kernel, initrd, and command line. This is temporary * memory allocation which is not needed any more after these buffers have * been loaded into separate segments and have been copied elsewhere. */void kimage_file_post_load_cleanup(struct kimage *image){	struct purgatory_info *pi = &image->purgatory_info; 	vfree(image->kernel_buf);	image->kernel_buf = NULL; 	vfree(image->initrd_buf);	image->initrd_buf = NULL; 	kfree(image->cmdline_buf);	image->cmdline_buf = NULL; 	vfree(pi->purgatory_buf);	pi->purgatory_buf = NULL; 	vfree(pi->sechdrs);	pi->sechdrs = NULL; 	/* See if architecture has anything to cleanup post load */	arch_kimage_file_post_load_cleanup(image); 	/*	 * Above call should have called into bootloader to free up	 * any data stored in kimage->image_loader_data. It should	 * be ok now to free it up.	 */	kfree(image->image_loader_data);	image->image_loader_data = NULL;} #ifdef CONFIG_KEXEC_SIGstatic intkimage_validate_signature(struct kimage *image){	int ret; 	ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,					   image->kernel_buf_len);	if (ret) { 		if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) {			pr_notice("Enforced kernel signature verification failed (%d).\n", ret);			return ret;		} 		/*		 * If IMA is guaranteed to appraise a signature on the kexec		 * image, permit it even if the kernel is otherwise locked		 * down.		 */		if (!ima_appraise_signature(READING_KEXEC_IMAGE) &&		    security_locked_down(LOCKDOWN_KEXEC))			return -EPERM; 		pr_debug("kernel signature verification failed (%d).\n", ret);	} 	return 0;}#endif /* * In file mode list of segments is prepared by kernel. Copy relevant * data from user space, do error checking, prepare segment list */static intkimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,			     const char __user *cmdline_ptr,			     unsigned long cmdline_len, unsigned flags){	int ret;	void *ldata;	loff_t size; 	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,				       &size, INT_MAX, READING_KEXEC_IMAGE);	if (ret)		return ret;	image->kernel_buf_len = size; 	/* Call arch image probe handlers */	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,					    image->kernel_buf_len);	if (ret)		goto out; #ifdef CONFIG_KEXEC_SIG	ret = kimage_validate_signature(image); 	if (ret)		goto out;#endif	/* It is possible that there no initramfs is being loaded */	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,					       &size, INT_MAX,					       READING_KEXEC_INITRAMFS);		if (ret)			goto out;		image->initrd_buf_len = size;	} 	if (cmdline_len) {		image->cmdline_buf = memdup_user(cmdline_ptr, cmdline_len);		if (IS_ERR(image->cmdline_buf)) {			ret = PTR_ERR(image->cmdline_buf);			image->cmdline_buf = NULL;			goto out;		} 		image->cmdline_buf_len = cmdline_len; 		/* command line should be a string with last byte null */		if (image->cmdline_buf[cmdline_len - 1] != '\0') {			ret = -EINVAL;			goto out;		} 		ima_kexec_cmdline(kernel_fd, image->cmdline_buf,				  image->cmdline_buf_len - 1);	} 	/* IMA needs to pass the measurement list to the next kernel. */	ima_add_kexec_buffer(image); 	/* Call arch image load handlers */	ldata = arch_kexec_kernel_image_load(image); 	if (IS_ERR(ldata)) {		ret = PTR_ERR(ldata);		goto out;	} 	image->image_loader_data = ldata;out:	/* In case of error, free up all allocated memory in this function */	if (ret)		kimage_file_post_load_cleanup(image);	return ret;} static intkimage_file_alloc_init(struct kimage **rimage, int kernel_fd,		       int initrd_fd, const char __user *cmdline_ptr,		       unsigned long cmdline_len, unsigned long flags){	int ret;	struct kimage *image;	bool kexec_on_panic = flags & KEXEC_FILE_ON_CRASH; 	image = do_kimage_alloc_init();	if (!image)		return -ENOMEM; 	image->file_mode = 1; 	if (kexec_on_panic) {		/* Enable special crash kernel control page alloc policy. */		image->control_page = crashk_res.start;		image->type = KEXEC_TYPE_CRASH;	} 	ret = kimage_file_prepare_segments(image, kernel_fd, initrd_fd,					   cmdline_ptr, cmdline_len, flags);	if (ret)		goto out_free_image; 	ret = sanity_check_segment_list(image);	if (ret)		goto out_free_post_load_bufs; 	ret = -ENOMEM;	image->control_code_page = kimage_alloc_control_pages(image,					   get_order(KEXEC_CONTROL_PAGE_SIZE));	if (!image->control_code_page) {		pr_err("Could not allocate control_code_buffer\n");		goto out_free_post_load_bufs;	} 	if (!kexec_on_panic) {		image->swap_page = kimage_alloc_control_pages(image, 0);		if (!image->swap_page) {			pr_err("Could not allocate swap buffer\n");			goto out_free_control_pages;		}	} 	*rimage = image;	return 0;out_free_control_pages:	kimage_free_page_list(&image->control_pages);out_free_post_load_bufs:	kimage_file_post_load_cleanup(image);out_free_image:	kfree(image);	return ret;} SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,		unsigned long, cmdline_len, const char __user *, cmdline_ptr,		unsigned long, flags){	int ret = 0, i;	struct kimage **dest_image, *image; 	/* We only trust the superuser with rebooting the system. */	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)		return -EPERM; 	/* Make sure we have a legal set of flags */	if (flags != (flags & KEXEC_FILE_FLAGS))		return -EINVAL; 	image = NULL; 	if (!mutex_trylock(&kexec_mutex))		return -EBUSY; 	dest_image = &kexec_image;	if (flags & KEXEC_FILE_ON_CRASH) {		dest_image = &kexec_crash_image;		if (kexec_crash_image)			arch_kexec_unprotect_crashkres();	} 	if (flags & KEXEC_FILE_UNLOAD)		goto exchange; 	/*	 * In case of crash, new kernel gets loaded in reserved region. It is	 * same memory where old crash kernel might be loaded. Free any	 * current crash dump kernel before we corrupt it.	 */	if (flags & KEXEC_FILE_ON_CRASH)		kimage_free(xchg(&kexec_crash_image, NULL)); 	ret = kimage_file_alloc_init(&image, kernel_fd, initrd_fd, cmdline_ptr,				     cmdline_len, flags);	if (ret)		goto out; 	ret = machine_kexec_prepare(image);	if (ret)		goto out; 	/*	 * Some architecture(like S390) may touch the crash memory before	 * machine_kexec_prepare(), we must copy vmcoreinfo data after it.	 */	ret = kimage_crash_copy_vmcoreinfo(image);	if (ret)		goto out; 	ret = kexec_calculate_store_digests(image);	if (ret)		goto out; 	for (i = 0; i < image->nr_segments; i++) {		struct kexec_segment *ksegment; 		ksegment = &image->segment[i];		pr_debug("Loading segment %d: buf=0x%p bufsz=0x%zx mem=0x%lx memsz=0x%zx\n",			 i, ksegment->buf, ksegment->bufsz, ksegment->mem,			 ksegment->memsz); 		ret = kimage_load_segment(image, &image->segment[i]);		if (ret)			goto out;	} 	kimage_terminate(image); 	ret = machine_kexec_post_load(image);	if (ret)		goto out; 	/*	 * Free up any temporary buffers allocated which are not needed	 * after image has been loaded	 */	kimage_file_post_load_cleanup(image);exchange:	image = xchg(dest_image, image);out:	if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)		arch_kexec_protect_crashkres(); 	mutex_unlock(&kexec_mutex);	kimage_free(image);	return ret;} static int locate_mem_hole_top_down(unsigned long start, unsigned long end,				    struct kexec_buf *kbuf){	struct kimage *image = kbuf->image;	unsigned long temp_start, temp_end; 	temp_end = min(end, kbuf->buf_max);	temp_start = temp_end - kbuf->memsz; 	do {		/* align down start */		temp_start = temp_start & (~(kbuf->buf_align - 1)); 		if (temp_start < start || temp_start < kbuf->buf_min)			return 0; 		temp_end = temp_start + kbuf->memsz - 1; 		/*		 * Make sure this does not conflict with any of existing		 * segments		 */		if (kimage_is_destination_range(image, temp_start, temp_end)) {			temp_start = temp_start - PAGE_SIZE;			continue;		} 		/* We found a suitable memory range */		break;	} while (1); 	/* If we are here, we found a suitable memory range */	kbuf->mem = temp_start; 	/* Success, stop navigating through remaining System RAM ranges */	return 1;} static int locate_mem_hole_bottom_up(unsigned long start, unsigned long end,				     struct kexec_buf *kbuf){	struct kimage *image = kbuf->image;	unsigned long temp_start, temp_end; 	temp_start = max(start, kbuf->buf_min); 	do {		temp_start = ALIGN(temp_start, kbuf->buf_align);		temp_end = temp_start + kbuf->memsz - 1; 		if (temp_end > end || temp_end > kbuf->buf_max)			return 0;		/*		 * Make sure this does not conflict with any of existing		 * segments		 */		if (kimage_is_destination_range(image, temp_start, temp_end)) {			temp_start = temp_start + PAGE_SIZE;			continue;

Lines 1–500 of 1347.