---
id: CVE-2026-89767
title: 'ovl: fix double end_creating() on the casefold-mismatch path'
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  ovl: fix double end_creating() on the casefold-mismatch path

  ovl_create_real() releases the new dentry twice when the casefold
  consistency check fails.  The S_IFDIR br…
severity: high
cvss: 7.8
cvssVector: 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H'
cvssSource: cna
cwe:
  - CWE-1341
vendor: Linux
product: Linux
affected:
  - >-
    Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af <
    2fa220bc0f84597cb6de665e5b5021c5901ddf00
  - >-
    Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af <
    b1aa8ab78a8e87aee9e306971465408e059f839a
  - >-
    Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af <
    077ab8985ee278c3d8618182d335b0f0cd919e16
  - Linux 6.18
published: '2026-09-11'
updated: '2026-10-19'
sourceUpdated: '2026-10-19T08:52:20.802Z'
source: CVEORG
sourceUrl: 'https://www.cve.org/CVERecord?id=CVE-2026-89767'
references:
  - url: 'https://git.kernel.org/stable/c/2fa220bc0f84597cb6de665e5b5021c5901ddf00'
  - url: 'https://git.kernel.org/stable/c/b1aa8ab78a8e87aee9e306971465408e059f839a'
  - url: 'https://git.kernel.org/stable/c/077ab8985ee278c3d8618182d335b0f0cd919e16'
  - url: >-
      https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-89767.json
  - url: 'https://access.redhat.com/security/cve/CVE-2026-89767'
  - url: 'https://bugzilla.redhat.com/show_bug.cgi?id=2532416'
  - url: 'https://www.cve.org/CVERecord?id=CVE-2026-89767'
  - url: 'https://nvd.nist.gov/vuln/detail/CVE-2026-89767'
  - url: >-
      https://git.kernel.org/pub/scm/linux/security/vulns.git/plain/cve/published/2026/CVE-2026-89767.mbox
tags:
  - cve.org
  - csaf
  - vex
  - red-hat
  - score-dispute
epss: 0.00173
epssPercentile: 0.06733
scores:
  cna: 7.8
  vendor: 5.5
ingestedAt: '2026-09-14T15:23:07.472Z'
---

## Overview

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

ovl: fix double end_creating() on the casefold-mismatch path

ovl_create_real() releases the new dentry twice when the casefold
consistency check fails.  The S_IFDIR branch calls end_creating() and
sets err, then falls through to the common out: label which calls
end_creating() on the same dentry again:

	case S_IFDIR:
		newdentry = ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
		err = PTR_ERR_OR_ZERO(newdentry);
		if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
			pr_warn_ratelimited(...);
			end_creating(newdentry);	/* first */
			err = -EINVAL;
		}
		break;
	...
	if (err)
		goto out;
	...
 out:
	if (err) {
		end_creating(newdentry);	/* second, same dentry */
		return ERR_PTR(err);
	}

end_creating() is end_dirop(), which does inode_unlock() on the parent
and dput() on the dentry, so the parent directory's i_rwsem is unlocked
twice and the dentry is put twice.  The second unlock releases a lock
that is not held, which is what wedges every later creation under that
parent, and the second dput() drops a reference that was never taken.

The branch was added by commit dfc7da402ccc ("ovl: Check for casefold
consistency when creating new dentries") as a bare dput(), which already
released the reference twice; commit fe497f0759e0 ("VFS: change
vfs_mkdir() to unlock on failure.") converted both sites to
end_creating(), adding the double unlock.

This is reachable by an unprivileged user.  The casefold consistency of
the layers is validated at mount time in ovl_parse_layer(), and again on
every lookup in ovl_lookup_single(), but ofs->workdir is the internal
"work" subdirectory created inside the user-supplied workdir, and that
subdirectory is not re-checked.  Marking it casefolded after the mount
therefore makes every ovl_create_temp() inherit the wrong state - and
that path reaches ovl_create_real() through ovl_start_creating_temp(),
which uses start_creating() with a generated name and so never runs the
lookup-time check.

  unshare -Urm
  mount -t tmpfs -o casefold=utf8-12.1.0 tmpfs mnt
  mkdir -p mnt/lower/d mnt/upper mnt/work mnt/merged
  mount -t overlay ovl -o lowerdir=mnt/lower,\
        upperdir=mnt/upper,workdir=mnt/work mnt/merged
  chattr +F mnt/work/work
  mkdir mnt/merged/d/sub		# directory copy-up

  overlayfs: wrong inherited casefold (work/#5)

and the next copy-up blocks forever on the parent's i_rwsem:

  mkdir           D  start_creating+0x65/0xb0
                     ovl_start_creating_temp+0xb0/0xe0 [overlay]
                     ovl_create_temp+0xa3/0x1d0 [overlay]
                     ovl_copy_up_one+0x1f1c/0x21c0 [overlay]
                     ovl_copy_up_flags+0xf5/0x140 [overlay]
                     ovl_create_object+0xb7/0x220 [overlay]
                     ovl_mkdir+0x23/0x40 [overlay]

Drop the end_creating() from the branch and let out: own the cleanup,
which is what every other error path in this function already does.

## Affected

- `Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af < 2fa220bc0f84597cb6de665e5b5021c5901ddf00`
- `Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af < b1aa8ab78a8e87aee9e306971465408e059f839a`
- `Linux >= dfc7da402ccc92d6e4b01a4778a3f15f2496b9af < 077ab8985ee278c3d8618182d335b0f0cd919e16`
- `Linux 6.18`

## Remediation

Refer to the linked advisories for vendor-supplied fixes and affected version ranges.

## Vendor advisories

- **Red Hat VEX** · Moderate · updated 2026-09-15 · [vex](https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-89767.json)
