Commit 731ae3ad authored by Petr Mladek's avatar Petr Mladek
Browse files

Merge branch 'for-6.17-hash_pointers' into for-linus

parents 3bfd34ed de1c831a
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -1798,6 +1798,27 @@
			backtraces on all cpus.
			Format: 0 | 1

	hash_pointers=
			[KNL,EARLY]
			By default, when pointers are printed to the console
			or buffers via the %p format string, that pointer is
			"hashed", i.e. obscured by hashing the pointer value.
			This is a security feature that hides actual kernel
			addresses from unprivileged users, but it also makes
			debugging the kernel more difficult since unequal
			pointers can no longer be compared. The choices are:
			Format: { auto | always | never }
			Default: auto

			auto   - Hash pointers unless slab_debug is enabled.
			always - Always hash pointers (even if slab_debug is
				 enabled).
			never  - Never hash pointers. This option should only
				 be specified when debugging the kernel. Do
				 not use on production kernels. The boot
				 param "no_hash_pointers" is an alias for
				 this mode.

	hashdist=	[KNL,NUMA] Large hashes allocated during boot
			are distributed across NUMA nodes.  Defaults on
			for 64-bit NUMA, off otherwise.
@@ -4120,18 +4141,7 @@

	no_hash_pointers
			[KNL,EARLY]
			Force pointers printed to the console or buffers to be
			unhashed.  By default, when a pointer is printed via %p
			format string, that pointer is "hashed", i.e. obscured
			by hashing the pointer value.  This is a security feature
			that hides actual kernel addresses from unprivileged
			users, but it also makes debugging the kernel more
			difficult since unequal pointers can no longer be
			compared.  However, if this command-line option is
			specified, then all normal pointers will have their true
			value printed. This option should only be specified when
			debugging the kernel.  Please do not use on production
			kernels.
			Alias for "hash_pointers=never".

	nohibernate	[HIBERNATION] Disable hibernation and resume.

@@ -6481,6 +6491,10 @@
			Documentation/mm/slub.rst.
			(slub_debug legacy name also accepted for now)

			Using this option implies the "no_hash_pointers"
			option which can be undone by adding the
			"hash_pointers=always" option.

	slab_max_order= [MM]
			Determines the maximum allowed order for slabs.
			A high setting may cause OOMs due to memory
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ __scanf(2, 0) int vsscanf(const char *, const char *, va_list);

/* These are for specific cases, do not use without real need */
extern bool no_hash_pointers;
int no_hash_pointers_enable(char *str);
void hash_pointers_finalize(bool slub_debug);

/* Used for Rust formatting ('%pA') */
char *rust_fmt_argument(char *buf, char *end, const void *ptr);
+57 −4
Original line number Diff line number Diff line
@@ -60,6 +60,20 @@
bool no_hash_pointers __ro_after_init;
EXPORT_SYMBOL_GPL(no_hash_pointers);

/*
 * Hashed pointers policy selected by "hash_pointers=..." boot param
 *
 * `auto`   - Hashed pointers enabled unless disabled by slub_debug_enabled=true
 * `always` - Hashed pointers enabled unconditionally
 * `never`  - Hashed pointers disabled unconditionally
 */
enum hash_pointers_policy {
	HASH_PTR_AUTO = 0,
	HASH_PTR_ALWAYS,
	HASH_PTR_NEVER
};
static enum hash_pointers_policy hash_pointers_mode __initdata;

noinline
static unsigned long long simple_strntoull(const char *startp, char **endp, unsigned int base, size_t max_chars)
{
@@ -2270,12 +2284,23 @@ char *resource_or_range(const char *fmt, char *buf, char *end, void *ptr,
	return resource_string(buf, end, ptr, spec, fmt);
}

int __init no_hash_pointers_enable(char *str)
void __init hash_pointers_finalize(bool slub_debug)
{
	if (no_hash_pointers)
		return 0;

	switch (hash_pointers_mode) {
	case HASH_PTR_ALWAYS:
		no_hash_pointers = false;
		break;
	case HASH_PTR_NEVER:
		no_hash_pointers = true;
		break;
	case HASH_PTR_AUTO:
	default:
		no_hash_pointers = slub_debug;
		break;
	}

	if (!no_hash_pointers)
		return;

	pr_warn("**********************************************************\n");
	pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
@@ -2288,11 +2313,39 @@ int __init no_hash_pointers_enable(char *str)
	pr_warn("** the kernel, report this immediately to your system   **\n");
	pr_warn("** administrator!                                       **\n");
	pr_warn("**                                                      **\n");
	pr_warn("** Use hash_pointers=always to force this mode off      **\n");
	pr_warn("**                                                      **\n");
	pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
	pr_warn("**********************************************************\n");
}

static int __init hash_pointers_mode_parse(char *str)
{
	if (!str) {
		pr_warn("Hash pointers mode empty; falling back to auto.\n");
		hash_pointers_mode = HASH_PTR_AUTO;
	} else if (strncmp(str, "auto", 4) == 0)   {
		pr_info("Hash pointers mode set to auto.\n");
		hash_pointers_mode = HASH_PTR_AUTO;
	} else if (strncmp(str, "never", 5) == 0) {
		pr_info("Hash pointers mode set to never.\n");
		hash_pointers_mode = HASH_PTR_NEVER;
	} else if (strncmp(str, "always", 6) == 0) {
		pr_info("Hash pointers mode set to always.\n");
		hash_pointers_mode = HASH_PTR_ALWAYS;
	} else {
		pr_warn("Unknown hash_pointers mode '%s' specified; assuming auto.\n", str);
		hash_pointers_mode = HASH_PTR_AUTO;
	}

	return 0;
}
early_param("hash_pointers", hash_pointers_mode_parse);

static int __init no_hash_pointers_enable(char *str)
{
	return hash_pointers_mode_parse("never");
}
early_param("no_hash_pointers", no_hash_pointers_enable);

/*
+2 −3
Original line number Diff line number Diff line
@@ -6314,9 +6314,8 @@ void __init kmem_cache_init(void)
	if (debug_guardpage_minorder())
		slub_max_order = 0;

	/* Print slub debugging pointers without hashing */
	if (__slub_debug_enabled())
		no_hash_pointers_enable(NULL);
	/* Inform pointer hashing choice about slub debugging state. */
	hash_pointers_finalize(__slub_debug_enabled());

	kmem_cache_node = &boot_kmem_cache_node;
	kmem_cache = &boot_kmem_cache;