public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Ezrak1e <ezrakiez@gmail.com>,
	Alexander Aring <aahringo@redhat.com>,
	David Teigland <teigland@redhat.com>,
	Sasha Levin <sashal@kernel.org>,
	gfs2@lists.linux.dev
Subject: [PATCH AUTOSEL 6.19-6.12] dlm: validate length in dlm_search_rsb_tree
Date: Tue, 10 Feb 2026 18:30:57 -0500	[thread overview]
Message-ID: <20260210233123.2905307-12-sashal@kernel.org> (raw)
In-Reply-To: <20260210233123.2905307-1-sashal@kernel.org>

From: Ezrak1e <ezrakiez@gmail.com>

[ Upstream commit 080e5563f878c64e697b89e7439d730d0daad882 ]

The len parameter in dlm_dump_rsb_name() is not validated and comes
from network messages. When it exceeds DLM_RESNAME_MAXLEN, it can
cause out-of-bounds write in dlm_search_rsb_tree().

Add length validation to prevent potential buffer overflow.

Signed-off-by: Ezrak1e <ezrakiez@gmail.com>
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Indeed, `dlm_copy_master_names` calls `find_rsb_root` with `inlen` that
comes from network data (`receive_rcom_names` →
`dlm_copy_master_names`). `inlen` is derived from
`rc_in->rc_header.h_length - sizeof(struct dlm_rcom)` with no bounds
check. And `find_rsb_root` doesn't validate it before passing to
`dlm_search_rsb_tree`.

So there are **at least two** unvalidated network-
to-`dlm_search_rsb_tree` paths:
1. `receive_rcom_lookup` → `dlm_dump_rsb_name` → `dlm_search_rsb_tree`
   (debug dump path)
2. `receive_rcom_names` → `dlm_copy_master_names` → `find_rsb_root` →
   `dlm_search_rsb_tree`

Both can pass `len > DLM_RESNAME_MAXLEN` (64), causing `memcpy(key,
name, len)` to overflow the stack buffer `key[DLM_RESNAME_MAXLEN]`.

Now let me verify what `DLM_RESNAME_MAXLEN` is:

The value is 64 (from `include/uapi/linux/dlmconstants.h`). The stack
buffer `key` is 64 bytes. If `len` > 64, `memcpy(key, name, len)` writes
beyond the buffer — a classic **stack buffer overflow**.

This is exploitable from a malicious DLM cluster node sending a crafted
network message.

## Detailed Analysis

### 1. COMMIT MESSAGE ANALYSIS

The commit message clearly states:
- The `len` parameter comes from **network messages** (untrusted input)
- When `len` exceeds `DLM_RESNAME_MAXLEN` (64), it causes an **out-of-
  bounds write** in `dlm_search_rsb_tree()`
- The fix adds length validation to prevent the buffer overflow

### 2. CODE CHANGE ANALYSIS

The change is extremely small and surgical — just 2 lines added:

```625:636:fs/dlm/lock.c
int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name, int
len,
                        struct dlm_rsb **r_ret)
{
        char key[DLM_RESNAME_MAXLEN] = {};
        // NEW: if (len > DLM_RESNAME_MAXLEN) return -EINVAL;
        memcpy(key, name, len);
        // ...
}
```

Without the check, `memcpy(key, name, len)` with `len > 64` writes past
the end of the 64-byte stack buffer `key`. This is a **stack buffer
overflow** — one of the most dangerous vulnerability classes in C.

### 3. VULNERABLE CODE PATHS

I traced all 6 callers of `dlm_search_rsb_tree`:

| Caller | Validates `len`? | Network-reachable? |
|--------|------------------|--------------------|
| `find_rsb_dir` | YES (via `find_rsb` at line 1089) | Yes |
| `find_rsb_nodir` | YES (via `find_rsb` at line 1089) | Yes |
| `_dlm_master_lookup` | YES (line 1268) | Yes |
| `receive_remove` | YES (line 4300) | Yes |
| **`dlm_dump_rsb_name`** | **NO** | **Yes** (via `receive_rcom_lookup`)
|
| **`find_rsb_root`** | **NO** | **Yes** (via `receive_rcom_names` →
`dlm_copy_master_names`) |

Two callers do NOT validate `len` before calling `dlm_search_rsb_tree`,
and both are reachable from network messages:

1. **`receive_rcom_lookup`** (rcom.c:379): When `rc_in->rc_id ==
   0xFFFFFFFF`, it calls `dlm_dump_rsb_name(ls, rc_in->rc_buf, len)`
   where `len` is derived from `rc_in->rc_header.h_length` (a network-
   supplied 16-bit field). No bounds check.

2. **`receive_rcom_names`** (rcom.c:336): Calculates `inlen` from
   `rc_in->rc_header.h_length - sizeof(struct dlm_rcom)` and passes it
   directly to `dlm_copy_master_names` → `find_rsb_root` →
   `dlm_search_rsb_tree`. No bounds check.

### 4. BUG SEVERITY

This is a **stack buffer overflow triggered by network input** in the
DLM (Distributed Lock Manager) subsystem:

- **Type**: Out-of-bounds write (stack buffer overflow)
- **Attack vector**: Network (DLM cluster communication protocol)
- **Trigger**: A malicious or buggy DLM cluster node sending a message
  with `h_length` large enough to make the extracted `len` exceed 64
- **Impact**: Stack corruption, potential code execution, kernel
  crash/panic
- **DLM context**: DLM is used in cluster filesystems like GFS2 and
  OCFS2, which are used in production enterprise environments

While the attack surface requires being part of a DLM cluster (not
publicly internet-reachable in most deployments), this is still a
serious security bug. In shared hosting or cloud environments, cluster
node compromise could lead to kernel-level exploitation of other cluster
members.

### 5. FIX QUALITY

The fix is **defense-in-depth at the right layer**:
- Rather than fixing each individual caller, it adds the validation in
  `dlm_search_rsb_tree` itself
- This protects against any future caller that might forget to validate
- The fix returns `-EINVAL`, which all callers handle (they all check
  the return value)
- It's only 2 lines, extremely low risk of regression
- The pattern is identical to the existing checks in
  `_dlm_master_lookup` (line 1268) and `receive_remove` (line 4300)

### 6. SCOPE AND RISK

- **Lines changed**: 2 (added `if` check and return)
- **Files changed**: 1 (`fs/dlm/lock.c`)
- **Risk of regression**: Extremely low — it adds a bounds check that
  was already present in 4 of 6 callers
- **Subsystem**: DLM (mature, production-critical for cluster
  filesystems)

### 7. APPLICABILITY TO STABLE

- The function `dlm_search_rsb_tree` was introduced in commit
  `5be323b0c64db` ("dlm: move dlm_search_rsb_tree() out of lock") from
  August 2024, which was merged in 6.12
- Older kernels may have equivalent vulnerable code but with different
  structure
- For 6.12+ stable trees, the fix should apply cleanly

### 8. STABLE CRITERIA CHECK

- Obviously correct and tested: YES (trivial bounds check, accepted by
  DLM maintainers Alexander Aring and David Teigland)
- Fixes a real bug: YES (stack buffer overflow from network input)
- Fixes an important issue: YES (security vulnerability — buffer
  overflow exploitable from network)
- Small and contained: YES (2 lines in 1 file)
- No new features or APIs: YES (pure bug fix)

**YES**

 fs/dlm/lock.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index c01a291db401b..a393ecaf3442a 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -626,7 +626,8 @@ int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name, int len,
 			struct dlm_rsb **r_ret)
 {
 	char key[DLM_RESNAME_MAXLEN] = {};
-
+	if (len > DLM_RESNAME_MAXLEN)
+		return -EINVAL;
 	memcpy(key, name, len);
 	*r_ret = rhashtable_lookup_fast(rhash, &key, dlm_rhash_rsb_params);
 	if (*r_ret)
-- 
2.51.0


  parent reply	other threads:[~2026-02-10 23:31 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-10 23:30 [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Reset RING_OPERATION1 fields during init Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-5.15] gfs2: fiemap page fault fix Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] dlm: fix recovery pending middle conversion Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.6] smb: client: prevent races in ->query_interfaces() Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Ensure proper bus clean-up Sasha Levin
2026-02-11  7:56   ` Adrian Hunter
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-5.10] audit: add fchmodat2() to change attributes class Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] btrfs: fallback to buffered IO if the data profile has duplication Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19] btrfs: don't BUG() on unexpected delayed ref type in run_one_delayed_ref() Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci-pci: Add System Suspend support Sasha Levin
2026-02-11  7:57   ` Adrian Hunter
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] hfsplus: fix volume corruption issue for generic/480 Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] kselftest/kublk: include message in _Static_assert for C11 compatibility Sasha Levin
2026-02-10 23:30 ` Sasha Levin [this message]
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] i3c: mipi-i3c-hci: Stop reading Extended Capabilities if capability ID is 0 Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.1] fs/buffer: add alert in try_to_free_buffers() for folios without buffers Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.15] i3c: master: svc: Initialize 'dev' to NULL in svc_i3c_master_ibi_isr() Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.12] statmount: permission check should return EPERM Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] audit: add missing syscalls to read class Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] hfsplus: pretend special inodes as regular files Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] hfsplus: fix volume corruption issue for generic/498 Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.18] netfs: when subreq is marked for retry, do not check if it faced an error Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19] hfs: Replace BUG_ON with error handling for CNID count checks Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.1] smb: client: add proper locking around ses->iface_last_update Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.6] btrfs: handle user interrupt properly in btrfs_trim_fs() Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] minix: Add required sanity checking to minix_check_superblock() Sasha Levin
2026-02-11  7:56 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Reset RING_OPERATION1 fields during init Adrian Hunter

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=20260210233123.2905307-12-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=aahringo@redhat.com \
    --cc=ezrakiez@gmail.com \
    --cc=gfs2@lists.linux.dev \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=teigland@redhat.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