---
id: CVE-2026-52990
title: |-
  In the Linux kernel, the following vulnerability has been resolved:

  fsnotify: fix inode reference leak in fsnotify_recalc_mask()

  fsnotify_recalc_mask() fails to handle the return value of
  __fsnotify_recalc_mask(), which may return an i…
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  fsnotify: fix inode reference leak in fsnotify_recalc_mask()

  fsnotify_recalc_mask() fails to handle the return value of
  __fsnotify_recalc_mask(), which may return an i…
severity: none
published: '2026-06-24'
updated: '2026-07-10'
source: NVD
sourceUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-52990'
references:
  - url: 'https://git.kernel.org/stable/c/4aca914ac152f5d055ddcb36704d1e539ac08977'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
  - url: 'https://git.kernel.org/stable/c/5c80289503da3658e3df80280598c68d181eadbd'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
  - url: 'https://git.kernel.org/stable/c/8c8afa6444e6bdc145d2bf2f3aeeca6da3e36b42'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
  - url: 'https://git.kernel.org/stable/c/b740cc86816bbc87902ae9db74cd21abde3c8d63'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
tags:
  - nvd
epss: 0.00127
epssPercentile: 0.0204
ingestedAt: '2026-07-11T13:13:25.601Z'
---

## Overview

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

fsnotify: fix inode reference leak in fsnotify_recalc_mask()

fsnotify_recalc_mask() fails to handle the return value of
__fsnotify_recalc_mask(), which may return an inode pointer that needs
to be released via fsnotify_drop_object() when the connector's HAS_IREF
flag transitions from set to cleared.

This manifests as a hung task with the following call trace:

  INFO: task umount:1234 blocked for more than 120 seconds.
  Call Trace:
   __schedule
   schedule
   fsnotify_sb_delete
   generic_shutdown_super
   kill_anon_super
   cleanup_mnt
   task_work_run
   do_exit
   do_group_exit

The race window that triggers the iref leak:

  Thread A (adding mark)              Thread B (removing mark)
  ──────────────────────              ────────────────────────
  fsnotify_add_mark_locked():
    fsnotify_add_mark_list():
      spin_lock(conn->lock)
      add mark_B(evictable) to list
      spin_unlock(conn->lock)
    return

    /* ---- gap: no lock held ---- */

                                      fsnotify_detach_mark(mark_A):
                                        spin_lock(mark_A->lock)
                                        clear ATTACHED flag on mark_A
                                        spin_unlock(mark_A->lock)
                                        fsnotify_put_mark(mark_A)

    fsnotify_recalc_mask():
      spin_lock(conn->lock)
      __fsnotify_recalc_mask():
        /* mark_A skipped: ATTACHED cleared */
        /* only mark_B(evictable) remains */
        want_iref = false
        has_iref = true  /* not yet cleared */
        -> HAS_IREF transitions true -> false
        -> returns inode pointer
      spin_unlock(conn->lock)
      /* BUG: return value discarded!
       * iput() and fsnotify_put_sb_watched_objects()
       * are never called */

Fix this by deferring the transition true -> false of HAS_IREF flag from
fsnotify_recalc_mask() (Thread A) to fsnotify_put_mark() (thread B).

## Remediation

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