Skip to content

In the Linux kernel, the following vulnerability has been...

High severity Unreviewed Published Feb 27, 2025 to the GitHub Advisory Database • Updated Feb 27, 2025

Package

No package listedSuggest a package

Affected versions

Unknown

Patched versions

Unknown

Description

In the Linux kernel, the following vulnerability has been resolved:

mm/slub: add missing TID updates on slab deactivation

The fastpath in slab_alloc_node() assumes that c->slab is stable as long as
the TID stays the same. However, two places in __slab_alloc() currently
don't update the TID when deactivating the CPU slab.

If multiple operations race the right way, this could lead to an object
getting lost; or, in an even more unlikely situation, it could even lead to
an object being freed onto the wrong slab's freelist, messing up the
inuse counter and eventually causing a page to be freed to the page
allocator while it still contains slab objects.

(I haven't actually tested these cases though, this is just based on
looking at the code. Writing testcases for this stuff seems like it'd be
a pain...)

The race leading to state inconsistency is (all operations on the same CPU
and kmem_cache):

  • task A: begin do_slab_free():
    • read TID
    • read pcpu freelist (==NULL)
    • check slab == c->slab (true)
  • [PREEMPT A->B]
  • task B: begin slab_alloc_node():
    • fastpath fails (c->freelist is NULL)
    • enter __slab_alloc()
    • slub_get_cpu_ptr() (disables preemption)
    • enter ___slab_alloc()
    • take local_lock_irqsave()
    • read c->freelist as NULL
    • get_freelist() returns NULL
    • write c->slab = NULL
    • drop local_unlock_irqrestore()
    • goto new_slab
    • slub_percpu_partial() is NULL
    • get_partial() returns NULL
    • slub_put_cpu_ptr() (enables preemption)
  • [PREEMPT B->A]
  • task A: finish do_slab_free():
    • this_cpu_cmpxchg_double() succeeds()
    • [CORRUPT STATE: c->slab==NULL, c->freelist!=NULL]

From there, the object on c->freelist will get lost if task B is allowed to
continue from here: It will proceed to the retry_load_slab label,
set c->slab, then jump to load_freelist, which clobbers c->freelist.

But if we instead continue as follows, we get worse corruption:

  • task A: run __slab_free() on object from other struct slab:
    • CPU_PARTIAL_FREE case (slab was on no list, is now on pcpu partial)
  • task A: run slab_alloc_node() with NUMA node constraint:
    • fastpath fails (c->slab is NULL)
    • call __slab_alloc()
    • slub_get_cpu_ptr() (disables preemption)
    • enter ___slab_alloc()
    • c->slab is NULL: goto new_slab
    • slub_percpu_partial() is non-NULL
    • set c->slab to slub_percpu_partial(c)
    • [CORRUPT STATE: c->slab points to slab-1, c->freelist has objects
      from slab-2]
    • goto redo
    • node_match() fails
    • goto deactivate_slab
    • existing c->freelist is passed into deactivate_slab()
    • inuse count of slab-1 is decremented to account for object from
      slab-2

At this point, the inuse count of slab-1 is 1 lower than it should be.
This means that if we free all allocated objects in slab-1 except for one,
SLUB will think that slab-1 is completely unused, and may free its page,
leading to use-after-free.

References

Published by the National Vulnerability Database Feb 26, 2025
Published to the GitHub Advisory Database Feb 27, 2025
Last updated Feb 27, 2025

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(16th percentile)

Weaknesses

CVE ID

CVE-2022-49700

GHSA ID

GHSA-p247-4v6m-f77m

Source code

No known source code

Dependabot alerts are not supported on this advisory because it does not have a package from a supported ecosystem with an affected and fixed version.

Learn more about GitHub language support

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.