public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: ven0mfuzzer <ven0mkernelfuzzer@gmail.com>
To: Viacheslav Dubeyko <slava@dubeyko.com>,
	Ilya Dryomov <idryomov@gmail.com>,
	Alex Markuze <amarkuze@redhat.com>
Cc: linux-kernel@vger.kernel.org, ceph-devel@vger.kernel.org
Subject: [BUG] OrangeFS Kernel Client Use-After-Free in atomic_dec_and_lock
Date: Thu, 02 Apr 2026 19:02:37 +0800	[thread overview]
Message-ID: <69ce4cce.050a0220.83ffb.e251@mx.google.com> (raw)

OrangeFS Kernel Client Use-After-Free in atomic_dec_and_lock

  1. Vulnerability Title

Linux Kernel OrangeFS/Ceph Client Use-After-Free Write in atomic_dec_and_lock via Corrupted Server Response (ceph_put_snapid_map)

  2. High-Level Overview

A use-after-free write vulnerability exists in the Linux kernel's Ceph filesystem layer, triggered via the OrangeFS kernel client. When a corrupted OrangeFS/Ceph server response causes inode state to become inconsistent, the `snapid_map` object is freed prematurely. A subsequent directory operation (`mkdir` → `lookup` → `d_invalidate` → `iput` → `evict`) calls `ceph_evict_inode()` → `ceph_put_snapid_map()`, which performs an `atomic_dec_and_lock()` on the already-freed `snapid_map` object — a 4-byte use-after-free write.

This is a moderate-severity vulnerability: the corrupted response may cause premature freeing of the snapid_map object, potentially leading to kernel memory corruption or denial of service when subsequently accessed.

This vulnerability was discovered using ven0mfuzzer, our custom-designed MITM-based network filesystem fuzzer developed by our team. Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact.

  3. Affected Product and Version Information

Product: Linux Kernel (upstream mainline)
Affected Component: `fs/ceph/snap.c` — `ceph_put_snapid_map()`; `fs/orangefs/` — OrangeFS kernel client triggering the code path

  Tested Version (confirmed vulnerable)
- Linux kernel 6.19.0 (mainline, commit `44331bd6a610`, gcc 11.4.0, built with KASAN + LOCKDEP + UBSAN + KFENCE)

  Affected Version Range
All kernels with `CONFIG_ORANGEFS_FS=y` and `CONFIG_CEPH_FS=y` are believed affected.

  Affected Environments

 |  Environment  |  Notes  | 
 | --- | --- | 
 |  HPC clusters using OrangeFS  |  Primary deployment target for OrangeFS  | 
 |  Research storage systems  |  Academic/lab environments with OrangeFS parallel storage  | 
 |  Any Linux system with CONFIG_ORANGEFS_FS  |  Not common in desktop distros; mainly HPC/research  | 

  4. Root Cause Analysis

  4.a. Detailed Description

The OrangeFS kernel client shares infrastructure with the Ceph filesystem, including inode management and snapid mapping. When a MITM-corrupted server response causes the kernel to build an inode with inconsistent snapshot state, the `snapid_map` reference count becomes mismanaged. The corrupted response leads to a premature free of the `snapid_map` object. When a subsequent directory operation triggers inode eviction via `ceph_evict_inode()`, it calls `ceph_put_snapid_map()` which performs `atomic_dec_and_lock()` on the already-freed memory — a 4-byte write to freed slab memory.

The fundamental issue is that the OrangeFS/Ceph client does not validate server-supplied inode attributes before using them to initialize internal kernel structures. Corrupted attributes lead to refcount mismanagement and eventually use-after-free.

  4.b. Code Flow

---
[Initial corruption — premature free]
pvfs2-client-core → /dev/pvfs2-req
  → orangefs_inode_getattr()
    → [corrupted inode attributes from server]
      → [snapid_map refcount becomes inconsistent]
        → [premature kfree of snapid_map]

[Trigger path — UAF write]
mkdir(2)
  → lookup_one_qstr_excl()
    → lookup_dcache()
      → d_invalidate()
        → shrink_dcache_tree()
          → shrink_dentry_list()
            → __dentry_kill()
              → dentry_unlink_inode()
                → iput()
                  → evict()
                    → ceph_evict_inode()
                      → ceph_put_snapid_map()
                        → atomic_dec_and_lock()    ← UAF WRITE (4 bytes)
---

  4.c. Crash Trace

This vulnerability was discovered by ven0mfuzzer. The following kernel trace is submitted following syzkaller's common practice of providing the raw crash trace as the primary reproduction evidence:

---
BUG: KASAN: slab-use-after-free in atomic_dec_and_lock+0x24/0x120
Write of size 4 at addr ffff888109374a68 by task mkdir/905

CPU: 1 UID: 0 PID: 905 Comm: mkdir Tainted: G W 6.19.0-g44331bd6a610-dirty #9 PREEMPT(lazy)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
Call Trace:
 <TASK>
 dump_stack_lvl+0xc6/0x120
 print_report+0xce/0x660
 kasan_report+0xe0/0x110
 kasan_check_range+0x105/0x1b0
 atomic_dec_and_lock+0x24/0x120
 ceph_put_snapid_map+0x3f/0x260
 ceph_evict_inode+0x2e8/0x890
 evict+0x3c2/0xad0
 iput+0x79a/0xd30
 dentry_unlink_inode+0x29c/0x480
 __dentry_kill+0x1d0/0x600
 shrink_dentry_list+0x134/0x680
 shrink_dcache_tree+0x100/0x5e0
 d_invalidate+0x13a/0x290
 lookup_dcache+0x13c/0x170
 lookup_one_qstr_excl+0x2a/0x250
 </TASK>
---

Reproduced 1 time.

  4.d. Suggested Fix

Add refcount validation in the inode initialization path when processing server-supplied attributes, and validate `snapid_map` is not already freed before decrementing:

---
/ In ceph_put_snapid_map(), add a refcount sanity check /
void ceph_put_snapid_map(struct ceph_snapid_map *sm)
{
    if (!sm)
        return;
+   if (WARN_ON(refcount_read(&sm->ref) == 0))
+       return;
    if (atomic_dec_and_lock(&sm->ref, &snap_empty_lock)) {
        ...
    }
}
---

The deeper fix should validate server-supplied inode attributes before using them to initialize internal kernel structures.

  5. Discovery Method and Reproduction

  5.a. Discovery

This vulnerability was discovered using ven0mfuzzer, a custom-designed MITM-based network filesystem fuzzer developed by our team. The fuzzer operates by positioning an AF_PACKET/TCP transparent proxy between a Linux kernel filesystem client (VM-A) and its server (VM-B), then mutating network protocol messages in-flight.

Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact.

  5.b. Reproduction Setup

---
VM-A (pvfs2 client + pvfs2-client-core) ──BMI/TCP port 3334──► Host (MITM proxy) ──TCP──► VM-B (pvfs2-server)
---

- Kernel: Linux 6.19.0 (commit `44331bd6a610`) with KASAN + LOCKDEP + UBSAN + KFENCE enabled
- Server: OrangeFS 2.10.0 (compiled with AddressSanitizer)
- Trigger: MITM mutation of server responses during directory operations causes inode corruption → premature snapid_map free → UAF on subsequent operation
- No standalone PoC — the crash trace above serves as the reproduction artifact

---
Reported-by: ven0mfuzzer <ven0mkernelfuzzer@gmail.com>
Link: https://github.com/KernelStackFuzz/KernelStackFuzz

             reply	other threads:[~2026-04-02 11:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-02 11:02 ven0mfuzzer [this message]
2026-04-02 18:45 ` [BUG] OrangeFS Kernel Client Use-After-Free in atomic_dec_and_lock Viacheslav Dubeyko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=69ce4cce.050a0220.83ffb.e251@mx.google.com \
    --to=ven0mkernelfuzzer@gmail.com \
    --cc=amarkuze@redhat.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=slava@dubeyko.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox