CVE-2026-68082CWE-125

CVE-2026-68082

Critical · published August 8, 2026

CVSS v3.1
9.8
EPSS
0%
Percentile
33.0
In the wild
Unconfirmed
What it is

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

libceph: fix two unsafe bare decodes in decode_lockers()

decode_lockers() in cls_lock_client.c contains two bare decode operations

that allow a malicious or compromised OSD to trigger slab-out-of-bounds

reads:

1. ceph_decode_32(p) at the num_lockers field has no preceding bounds

check. ceph_start_decoding() accepts struct_len=0 as valid -- the

internal ceph_decode_need(p, end, 0, bad) always passes -- so when an

OSD sends struct_len=0, ceph_start_decoding() returns success with

p == end. The immediately following bare ceph_decode_32(p) then reads

4 bytes past the validated buffer boundary. The garbage value is

passed directly to kzalloc_objs() as the locker count.

The sibling function decode_watchers() in osd_client.c already uses

ceph_decode_32_safe() after its own ceph_start_decoding() call.

decode_lockers() was the only site using the bare variant.

2. ceph_decode_8(p) after the decode_locker() loop has no preceding

bounds check. If an OSD crafts num_lockers such that the loop

advances p exactly to end, the subsequent bare ceph_decode_8(p) reads

one byte past the validated buffer boundary. The result is passed

directly into *type, which is used as a lock type discriminator by

callers, giving an OSD-controlled one-byte OOB read with direct

influence over the lock type field.

Fix both by replacing bare operations with their safe variants:

ceph_decode_32(p) -> ceph_decode_32_safe(p, end, *num_lockers,

err_inval)

ceph_decode_8(p) -> ceph_decode_8_safe(p, end, *type,

err_free_lockers)

The goto targets differ intentionally:

err_inval: is a new label returning -EINVAL directly. It is used for

the pre-allocation failure path where *lockers is not yet allocated

and must not be passed to ceph_free_lockers().

err_free_lockers: is the existing label. It is used for the

post-allocation failure path where *lockers is allocated and must

be freed.

ret is set to -EINVAL before ceph_decode_8_safe() so that

err_free_lockers returns the correct error code on bounds violation.

Without this, err_free_lockers would return a stale ret value (0 from

the successful decode_locker() loop), silently swallowing the error.

-EINVAL is correct for both failure paths. The data received from the

OSD is structurally malformed. -ENOMEM would misrepresent the failure

class to callers and to stable@ backporters triaging error paths.

Attacker model: a malicious or compromised OSD in a multi-tenant Ceph

deployment can trigger this against any kernel client that issues the

lock.get_info class method (e.g. during RBD exclusive lock acquisition).

[ idryomov: trim changelog, formatting ]

The record
Technical detail
CVSS v3.1
9.8 · CRITICAL
Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0
Not supplied
EPSS
0.00399 · 33.0th percentile
Weakness
CWE-125 · Out-of-bounds Read
Published
2026-08-08T14:16Z
References (8)
EPSS history
Timeline
  • 08 AUG 09:17Z
    libceph: fix two unsafe bare decodes in decode_lockers()
    cvelistv5