Commit 426e9a51 authored by Felix Fu's avatar Felix Fu
Browse files

x86/boot: add x86 nokaslr memory regions

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8RJ1I


CVE: NA

--------------------------------

allow users to mark at most 4 regions as not available for kaslr

Signed-off-by: default avatarFelix Fu <fuzhen5@huawei.com>
parent 9bac1dbc
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2155,6 +2155,18 @@ config RANDOMIZE_BASE

	  If unsure, say Y.

config KASLR_SKIP_MEM_RANGE
	bool "Skip specified memory range when randomize the kernel image"
	depends on RANDOMIZE_BASE
	default n
	help
	  Skip specified memory range when randomize the kernel image. This
	  feature support nokalsr kernel parameter in x86. Nokaslr kernel
	  parameters are described by the nokaslr=nn[KMG]-ss[KMG].
	  Region of memory to be reserved is from nn to ss. The region must
	  be in the range of existed memory, otherwise will be ignored.This
	  feature support up to 4 nokaslr regions.

# Relocation on x86 needs some additional build support
config X86_NEED_RELOCS
	def_bool y
+45 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ static unsigned long get_boot_seed(void)
/* Only supporting at most 4 unusable memmap regions with kaslr */
#define MAX_MEMMAP_REGIONS	4

#ifdef CONFIG_KASLR_SKIP_MEM_RANGE
#define MAX_MEM_NOKASLR_REGIONS 4
#endif

static bool memmap_too_large;


@@ -94,6 +98,10 @@ enum mem_avoid_index {
	MEM_AVOID_BOOTPARAMS,
	MEM_AVOID_MEMMAP_BEGIN,
	MEM_AVOID_MEMMAP_END = MEM_AVOID_MEMMAP_BEGIN + MAX_MEMMAP_REGIONS - 1,
#ifdef CONFIG_KASLR_SKIP_MEM_RANGE
	MEM_AVOID_MEM_NOKASLR_BEGIN,
	MEM_AVOID_MEM_NOKASLR_END = MEM_AVOID_MEM_NOKASLR_BEGIN + MAX_MEM_NOKASLR_REGIONS - 1,
#endif
	MEM_AVOID_MAX,
};

@@ -223,6 +231,39 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str)
		memmap_too_large = true;
}

#ifdef CONFIG_KASLR_SKIP_MEM_RANGE
static void mem_avoid_mem_nokaslr(char *str)
{
	int i = 0;

	while (str && (i < MAX_MEM_NOKASLR_REGIONS)) {
		char *oldstr;
		u64 start, end;
		char *k = strchr(str, ',');

		if (k)
			*k++ = 0;

		oldstr = str;
		start = memparse(str, &str);
		if (str == oldstr || *str != '-') {
			warn("Nokaslr values error.\n");
			break;
		}

		end = memparse(str + 1, &str);
		if (start >= end) {
			warn("Nokaslr values error, start should be less than end.\n");
			break;
		}

		mem_avoid[MEM_AVOID_MEM_NOKASLR_BEGIN + i].start = start;
		mem_avoid[MEM_AVOID_MEM_NOKASLR_BEGIN + i].size = end - start;
		str = k;
		i++;
	}
}
#endif
/* Store the number of 1GB huge pages which users specified: */
static unsigned long max_gb_huge_pages;

@@ -298,6 +339,10 @@ static void handle_mem_options(void)
		} else if (!strcmp(param, "efi_fake_mem")) {
			mem_avoid_memmap(PARSE_EFI, val);
		}
#ifdef CONFIG_KASLR_SKIP_MEM_RANGE
		else if (!strcmp(param, "nokaslr") && val)
			mem_avoid_mem_nokaslr(val);
#endif
	}

	free(tmp_cmdline);