Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31f8a651 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/tsc: Validate cpumask pointer before accessing it



0-day testing encountered a NULL pointer dereference in a cpumask access
from tsc_store_and_check_tsc_adjust().

This happens when the function is called on the boot CPU and the topology
masks are not yet available due to CPUMASK_OFFSTACK=y.

Add a NULL pointer check for the mask pointer. If NULL it's safe to assume
that the CPU is the boot CPU and the first one in the package.

Fixes: 8b223bc7 ("x86/tsc: Store and check TSC ADJUST MSR")
Reported-by: default avatarkernel test robot <xiaolong.ye@intel.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent b8365543
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ bool tsc_store_and_check_tsc_adjust(void)
{
{
	struct tsc_adjust *ref, *cur = this_cpu_ptr(&tsc_adjust);
	struct tsc_adjust *ref, *cur = this_cpu_ptr(&tsc_adjust);
	unsigned int refcpu, cpu = smp_processor_id();
	unsigned int refcpu, cpu = smp_processor_id();
	struct cpumask *mask;
	s64 bootval;
	s64 bootval;


	if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST))
	if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST))
@@ -98,9 +99,11 @@ bool tsc_store_and_check_tsc_adjust(void)
	 * Check whether this CPU is the first in a package to come up. In
	 * Check whether this CPU is the first in a package to come up. In
	 * this case do not check the boot value against another package
	 * this case do not check the boot value against another package
	 * because the package might have been physically hotplugged, where
	 * because the package might have been physically hotplugged, where
	 * TSC_ADJUST is expected to be different.
	 * TSC_ADJUST is expected to be different. When called on the boot
	 * CPU topology_core_cpumask() might not be available yet.
	 */
	 */
	refcpu = cpumask_any_but(topology_core_cpumask(cpu), cpu);
	mask = topology_core_cpumask(cpu);
	refcpu = mask ? cpumask_any_but(mask, cpu) : nr_cpu_ids;


	if (refcpu >= nr_cpu_ids) {
	if (refcpu >= nr_cpu_ids) {
		/*
		/*