From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 942524DC527; Mon, 20 Apr 2026 13:33:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776692029; cv=none; b=TWzYXvTLAA52V59/dqY2rWrYkfD3voaUZGb39ph+rgK+QIJDwS65FcOHkuwjGqeQZQWYY2X8fD2cmeEnPbI9nibmX83twvW9TJ3GZpMbASBQytaMjRhRVcXkn0bIZCi/EJLYfwFm20x5qaRvRxWAnkjqBv/7RwV6xcZL1SwPfk4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776692029; c=relaxed/simple; bh=kI5JVNp9MVMlPRc6VYu1r9vjEcn5Otqd4Y7FJptMpFg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rKMHSODVD2yJcKZ3e7CZ7sxy5mn/bVm+2EWPl3z4MI6w+n6X1BdWYgoRRX7IfwbnxGusa5pbRrcZM/Snno78OAF0DlWP+kWhGR9tJu9jPiHrhzGZtGwUiDAEmw42kfXPe4XtQJn3AKCeBrA6R9n4clw7R9Oa3Ay6N+Rpyc0+1cQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bH6xSMxn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bH6xSMxn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 638E3C19425; Mon, 20 Apr 2026 13:33:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776692029; bh=kI5JVNp9MVMlPRc6VYu1r9vjEcn5Otqd4Y7FJptMpFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bH6xSMxnSA5Qp0t1tQWsjfvCO0qG2JB34cvrr+0ZXPdi1gpbuIAtvkqTd9Num1tMD 0EM6CQtIGgvWkhnCQxFayq+axmA9eOyPvwHmcOEj76Dp1dnCX9pTv3fEzxzselp/Q5 1JihPZXUIvJ2dDzGAC80c5B3+SELYjPqgRkcdJ58lszkGZf4Ugg2m0Ry9s3SQvrOVg gRF4pWHS9EqU4z8iy4kaR/At6vQV0w4CVllLV3DzzEH0zJp9Q0juki0WXRzq7l5lRd WKVP4Wq9XtQ11HjDJILB1r3vjUZy9wvSvjZiIkqaEHWQoFWkZ6Pc3wI0ApeBhwvpQw 7mSkUVi1codkg== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: =?UTF-8?q?Jo=C3=A3o=20Paredes?= , Dave Kleikamp , Sasha Levin , shaggy@kernel.org, jfs-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH AUTOSEL 7.0-5.10] JFS: always load filesystem UUID during mount Date: Mon, 20 Apr 2026 09:22:07 -0400 Message-ID: <20260420132314.1023554-333-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org> References: <20260420132314.1023554-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 7.0 Content-Transfer-Encoding: 8bit From: João Paredes [ Upstream commit 679330e4a7af1d102d035b13b2b9d41bc1dfbbf7 ] The filesystem UUID was only being loaded into super_block sb when an external journal device was in use. When mounting without an external journal, the UUID remained unset, which prevented the computation of a filesystem ID (fsid), which could be confirmed via `stat -f -c "%i"` and thus user space could not use fanotify correctly. A missing filesystem ID causes fanotify to return ENODEV when marking the filesystem for events like FAN_CREATE, FAN_DELETE, FAN_MOVED_TO, and FAN_MOVED_FROM. As a result, applications relying on fanotify could not monitor these events on JFS filesystems without an external journal. Moved the UUID initialization so it is always performed during mount, ensuring the superblock UUID is consistently available. Signed-off-by: João Paredes Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: Now I have all the information needed for a thorough analysis. Let me compile it. --- ## PHASE 1: COMMIT MESSAGE FORENSICS ### Step 1.1: PARSE THE SUBJECT LINE - **Subsystem:** JFS (Journaled File System) - **Action verb:** "always load" (correcting behavior that should have been unconditional) - **Summary:** Ensures the filesystem UUID is always loaded during mount, not just when external journal is configured - Record: [JFS] [always load / ensure] [Fix UUID not being loaded for inline-log configurations, breaking fsid and fanotify] ### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS - **Signed-off-by: João Paredes ** - Author of the fix (no prior JFS commits found) - **Signed-off-by: Dave Kleikamp ** - JFS maintainer, signed off = reviewed and accepted - No Fixes: tag, no Reported-by, no Cc: stable (expected for this pipeline) - Record: Fix accepted by JFS subsystem maintainer. No explicit stable nomination. ### Step 1.3: ANALYZE THE COMMIT BODY TEXT The commit clearly describes the bug: - **Bug:** UUID only loaded when external journal used (`!JFS_INLINELOG` path); inline log (the default) left `sbi->uuid` unset (all zeros) - **Symptom:** `stat -f -c "%i"` returns 0 (no filesystem ID); fanotify returns `ENODEV` for `FAN_CREATE`, `FAN_DELETE`, `FAN_MOVED_TO`, `FAN_MOVED_FROM` - **Root cause:** `uuid_copy` was inside the else branch of the inline- log conditional - **Impact:** Applications relying on fanotify cannot monitor filesystem events on JFS - Record: Real functional bug with clear user-visible symptoms. Fanotify breaks for the default JFS configuration. ### Step 1.4: DETECT HIDDEN BUG FIXES Not hidden at all. The commit message is direct about the bug mechanism and user-visible impact. ## PHASE 2: DIFF ANALYSIS - LINE BY LINE ### Step 2.1: INVENTORY THE CHANGES - **File:** `fs/jfs/jfs_mount.c` only - **Lines added:** 2 (uuid_copy + blank line before if/else) - **Lines removed:** 1 (uuid_copy from else block) - **Net change:** +1 line - **Function modified:** `chkSuper()` - **Scope:** Single-file, surgical one-line fix - Record: [fs/jfs/jfs_mount.c: +2/-1] [chkSuper()] [Single-file surgical fix] ### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE **Before:** ```381:387:fs/jfs/jfs_mount.c if (sbi->mntflag & JFS_INLINELOG) sbi->logpxd = j_sb->s_logpxd; else { sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev)); uuid_copy(&sbi->uuid, &j_sb->s_uuid); uuid_copy(&sbi->loguuid, &j_sb->s_loguuid); } ``` **After:** `uuid_copy(&sbi->uuid, &j_sb->s_uuid)` is moved BEFORE the if/else block, making it unconditional. `uuid_copy(&sbi->loguuid, ...)` stays in else (correct - only needed for external log). ### Step 2.3: IDENTIFY THE BUG MECHANISM - **Category:** Logic/correctness fix - conditional initialization that should be unconditional - **What was broken:** UUID needed unconditionally (for fsid computation in `jfs_statfs()`), but was only loaded in the external-log path - **How the fix works:** Moves the uuid_copy call outside the conditional ### Step 2.4: ASSESS THE FIX QUALITY - **Obviously correct:** Yes - the UUID is a filesystem property, not a journal-specific property - **Minimal:** Yes - moving one line - **Regression risk:** Essentially zero. For the inline-log case, UUID is now properly populated (was zeros before). For the external-log case, behavior is identical. ## PHASE 3: GIT HISTORY INVESTIGATION ### Step 3.1: BLAME THE CHANGED LINES - The if/else structure dates to `^1da177e4c3f41` (Linux 2.6.12-rc2, 2005-04-16, Linus Torvalds) - present since initial git history - The `uuid_copy` line was updated by `2e3bc6125154c6` (Andy Shevchenko, 2019-01-10) - UUID API conversion only, didn't change the placement - The original code ALWAYS had the UUID copy inside the else branch - Record: Buggy placement dates to the initial Linux git import (v2.6.12). Present in ALL stable trees. ### Step 3.2: THE REAL FIXES TARGET The fsid computation using `sbi->uuid` was added by `b5c816a4f1776` (Coly Li, 2009-01-21, "jfs: return f_fsid for statfs(2)"). This commit added the CRC32-based fsid computation but didn't realize the UUID was only loaded for external-log configurations. So the actual bug was introduced in 2009 when the UUID became functionally significant beyond just external log tracking. ### Step 3.3-3.5: RELATED CHANGES - No recent JFS changes to jfs_mount.c affect this area - This is a standalone fix with no dependencies - Author João Paredes has no other JFS commits (first-time contributor), but the fix was accepted by JFS maintainer Dave Kleikamp ## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH ### Step 4.1-4.5 - Could not find the original patch submission on lore.kernel.org due to bot protection - The fix was accepted by Dave Kleikamp (JFS maintainer) which provides strong quality signal - No CVE was found for this specific issue ## PHASE 5: CODE SEMANTIC ANALYSIS ### Step 5.1-5.2: KEY FUNCTIONS AND CALLERS The impacted code path: 1. `chkSuper()` is called during `jfs_mount()` (line 83) and during `jfs_mount_rw()` remount (line 232) 2. `sbi->uuid` is consumed by: - `jfs_statfs()` in `fs/jfs/super.c` (lines 146-150) - computes `f_fsid` via CRC32 of UUID - `lmLogFileSystem()` in `fs/jfs/jfs_logmgr.c` (line 1713) - tracks active filesystems in log 3. `jfs_statfs()` is the VFS `.statfs` operation, called via `vfs_statfs()` and `vfs_get_fsid()` 4. `fanotify_test_fsid()` calls `vfs_get_fsid()` which calls `jfs_statfs()` - confirmed in `fs/notify/fanotify/fanotify_user.c` line 1771 ### Step 5.3-5.4: FANOTIFY ENODEV MECHANISM CONFIRMED In `fanotify_test_fsid()` (line 1776): ```1776:1779:fs/notify/fanotify/fanotify_user.c if (!fsid->id.val[0] && !fsid->id.val[1]) { err = -ENODEV; goto weak; } ``` When `sbi->uuid` is all zeros (kzalloc'd), `crc32_le(0, zeros, N) = 0` (CRC is linear, zero input with zero init = zero output). So `f_fsid = {0, 0}`, triggering the ENODEV path. The `weak` label returns `-ENODEV` for non-inode marks (FAN_MARK_FILESYSTEM, FAN_MARK_MOUNT). ### Step 5.5: SIMILAR PATTERNS The comment at line 1769 explicitly says: "Make sure dentry is not of a filesystem with zero fsid (e.g. fuse)." JFS was silently in this same broken category for inline-log configs. ## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS ### Step 6.1: BUGGY CODE EXISTS IN ALL STABLE TREES Confirmed via `git show v7.0-rc7:fs/jfs/jfs_mount.c` - the buggy conditional UUID loading is present. The code has been this way since the initial Linux git import and exists in ALL active stable trees. ### Step 6.2: BACKPORT COMPLICATIONS None. The patch will apply cleanly - the surrounding code in `chkSuper()` has been unchanged for years. ## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT ### Step 7.1: SUBSYSTEM CRITICALITY - **Subsystem:** JFS filesystem (fs/jfs/) - **Criticality:** IMPORTANT - filesystem correctness affects data and application behavior - JFS is a mature filesystem used particularly in enterprise environments ### Step 7.2: SUBSYSTEM ACTIVITY JFS receives minimal but ongoing maintenance, mostly bug fixes. ## PHASE 8: IMPACT AND RISK ASSESSMENT ### Step 8.1: WHO IS AFFECTED All JFS users mounting without an external journal (the default configuration). This is the vast majority of JFS users. ### Step 8.2: TRIGGER CONDITIONS - **How common:** Every single mount of a JFS filesystem with inline log - **User trigger:** Any application using fanotify with `FAN_MARK_FILESYSTEM` or `FAN_MARK_MOUNT` on JFS - **No special privileges needed** beyond normal fanotify access ### Step 8.3: FAILURE MODE SEVERITY - **Failure:** Applications using fanotify (file monitoring, security tools, backup software) get ENODEV and cannot monitor JFS filesystems - **Severity:** HIGH - functional breakage of a standard kernel interface for a standard filesystem configuration - Not a crash or security issue, but a clear functional bug affecting userspace applications ### Step 8.4: RISK-BENEFIT RATIO - **Benefit:** HIGH - fixes fanotify for all JFS users with inline log (the common case) - **Risk:** VERY LOW - 1 line moved, obviously correct, no possible regression - **Ratio:** Excellent ## PHASE 9: FINAL SYNTHESIS ### Step 9.1: EVIDENCE COMPILATION **FOR backporting:** - Fixes a real, user-visible bug: fanotify returns ENODEV for default JFS configurations - Extremely small and surgical fix: 1 line moved - Obviously correct: UUID is a filesystem property, not journal-specific - Accepted by JFS maintainer (Dave Kleikamp) - Bug affects ALL stable trees (code unchanged since initial git import) - Patch applies cleanly - Zero regression risk - Bug has existed since 2009 (fsid computation added) **AGAINST backporting:** - No Fixes: tag or Cc: stable (expected - that's why it needs review) - No syzbot/KASAN/crash - it's a functional bug, not a memory safety issue - Author is a first-time contributor (but fix accepted by maintainer) ### Step 9.2: STABLE RULES CHECKLIST 1. Obviously correct and tested? **YES** - trivially verifiable, accepted by maintainer 2. Fixes a real bug? **YES** - fanotify ENODEV for default JFS configuration 3. Important issue? **YES** - breaks standard kernel interface for application monitoring 4. Small and contained? **YES** - 1 line moved in 1 file 5. No new features or APIs? **YES** - just fixes existing behavior 6. Can apply to stable? **YES** - will apply cleanly to all stable trees ### Step 9.3: EXCEPTION CATEGORIES Not an exception category - this is a standard bug fix. ## Verification - [Phase 1] Parsed tags: Signed-off-by from author and JFS maintainer Dave Kleikamp - [Phase 2] Diff analysis: 1 line moved from else block to unconditional execution in `chkSuper()` - [Phase 3] git blame: buggy conditional structure present since `^1da177e4c3f41` (v2.6.12, 2005); fsid computation added in `b5c816a4f1776` (2009) made it functionally significant - [Phase 3] git show v7.0-rc7: confirmed buggy code exists unchanged in v7.0 stable tree - [Phase 5] Traced call chain: `fanotify_test_fsid()` -> `vfs_get_fsid()` -> `jfs_statfs()` -> CRC32 of `sbi->uuid`; confirmed zero-UUID produces zero fsid which triggers ENODEV at fanotify_user.c:1776-1777 - [Phase 5] Confirmed `sbi` allocated via `kzalloc_obj` in super.c:452, so uuid is zero-initialized - [Phase 5] Confirmed `JFS_INLINELOG` (0x00000800) is the default/common JFS configuration - [Phase 6] Code is identical across all stable trees - patch applies cleanly - [Phase 8] Failure mode: fanotify returns -ENODEV for FAN_MARK_FILESYSTEM/MOUNT on default JFS, severity HIGH - UNVERIFIED: Could not access lore.kernel.org for original patch discussion (bot protection blocked access) **YES** fs/jfs/jfs_mount.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 52e6b58c5dbd2..dac822f150701 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -378,11 +378,12 @@ static int chkSuper(struct super_block *sb) sbi->nbperpage = PSIZE >> sbi->l2bsize; sbi->l2nbperpage = L2PSIZE - sbi->l2bsize; sbi->l2niperblk = sbi->l2bsize - L2DISIZE; + uuid_copy(&sbi->uuid, &j_sb->s_uuid); + if (sbi->mntflag & JFS_INLINELOG) sbi->logpxd = j_sb->s_logpxd; else { sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev)); - uuid_copy(&sbi->uuid, &j_sb->s_uuid); uuid_copy(&sbi->loguuid, &j_sb->s_loguuid); } sbi->fsckpxd = j_sb->s_fsckpxd; -- 2.53.0