From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>,
Sasha Levin <sashal@kernel.org>,
ntfs3@lists.linux.dev
Subject: [PATCH AUTOSEL 6.18-5.15] fs/ntfs3: Support timestamps prior to epoch
Date: Mon, 8 Dec 2025 19:15:25 -0500 [thread overview]
Message-ID: <20251209001610.611575-33-sashal@kernel.org> (raw)
In-Reply-To: <20251209001610.611575-1-sashal@kernel.org>
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ]
Before it used an unsigned 64-bit type, which prevented proper handling
of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to
support pre-epoch timestamps. The issue was caught by xfstests.
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have a complete understanding. Let me write the detailed analysis:
## Detailed Analysis
### 1. COMMIT MESSAGE ANALYSIS
**Subject:** `fs/ntfs3: Support timestamps prior to epoch`
**Commit Body:**
- The commit explains that before this fix, the code used an **unsigned
64-bit type** (`u64`), which prevented proper handling of timestamps
earlier than 1970-01-01 (the Unix epoch).
- The fix switches to a **signed 64-bit type** (`s64`) to support pre-
epoch timestamps.
- The issue was caught by **xfstests test 258**, which specifically
tests for timestamps prior to the epoch.
**Tags:**
- **No `Cc: stable@vger.kernel.org` tag** is present.
- **No `Fixes:` tag** is present.
### 2. CODE CHANGE ANALYSIS
#### The Bug:
In the current code (before the patch):
```980:987:fs/ntfs3/ntfs_fs.h
static inline void nt2kernel(const __le64 tm, struct timespec64 *ts)
{
u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
// WARNING: do_div changes its first argument(!)
ts->tv_nsec = do_div(t, _100ns2seconds) * 100;
ts->tv_sec = t;
}
```
The variable `t` is declared as `u64` (unsigned 64-bit integer). NTFS
timestamps are stored as the number of 100-nanosecond intervals since
January 1, 1601. After subtracting `SecondsToStartOf1970`
(0x00000002B6109100), which represents the number of seconds between
1601 and 1970, `t` represents a Unix timestamp.
**Problem:** When the NTFS timestamp represents a date before January 1,
1970, the subtraction produces a **negative** result. But since `t` is
unsigned (`u64`), the negative value wraps around to a very large
positive value, resulting in a wrong (future) timestamp.
**The `do_div` macro** operates on unsigned integers and uses unsigned
division, which doesn't handle negative values correctly.
#### The Fix:
The patch changes:
1. `u64 t` → `s64 t` (signed 64-bit integer)
2. `do_div(t, _100ns2seconds)` → `div_s64_rem(t, _100ns2seconds, &t32)`
(signed division)
3. Introduces `s32 t32` to hold the remainder
The new code:
```c
static inline void nt2kernel(const __le64 tm, struct timespec64 *ts)
{
s32 t32;
/* use signed 64 bit to support timestamps prior to epoch.
xfstest 258. */
s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32);
ts->tv_nsec = t32 * 100;
}
```
`div_s64_rem()` is designed for signed 64-bit division with a 32-bit
divisor, properly handling negative values and returning the remainder
through a pointer.
**Root Cause:** Using unsigned arithmetic for a value that can be
negative (pre-epoch timestamps).
### 3. CLASSIFICATION
- **Bug fix:** YES - This is fixing incorrect behavior with timestamps
before 1970.
- **New feature:** NO - It doesn't add new functionality, only fixes
existing functionality.
- **Security fix:** NO - No security implications.
- **Exception category:** NO - Not a device ID, quirk, DT update, build
fix, or documentation fix.
### 4. SCOPE AND RISK ASSESSMENT
**Lines Changed:** Very minimal - changes ~8 lines of code within a
single inline function.
**Files Touched:** 1 file (`fs/ntfs3/ntfs_fs.h`)
**Subsystem Complexity:**
- NTFS3 is a relatively new filesystem (added in 5.15)
- The change is in a core time conversion function `nt2kernel()` that is
called whenever reading timestamps from disk
- All file timestamps (creation, modification, access times) use this
function
**Risk Assessment:**
- **LOW RISK** - The change is small, surgical, and uses a well-
established kernel API (`div_s64_rem`)
- The new code is mathematically equivalent to the old code for
timestamps after 1970
- For timestamps before 1970, the new code produces correct results
(negative `tv_sec` values)
- The `timespec64` structure's `tv_sec` field is `time64_t` which is
signed (`__s64`), so it can properly represent negative timestamps
### 5. USER IMPACT
**Who is affected?**
- Users of NTFS3 filesystem
- Users with NTFS volumes containing files with pre-1970 timestamps
**How severe?**
- The bug causes **data corruption** (incorrect timestamp
display/storage) for pre-epoch files
- Without this fix, timestamps like January 1, 1960 would appear as some
date far in the future
- This breaks file management tools and any software relying on correct
timestamps
**Test Coverage:**
- The fix was identified by **xfstests generic/258**, a standard
filesystem test that specifically validates pre-epoch timestamp
handling
- This is a well-known and commonly run test suite
### 6. STABILITY INDICATORS
- **No `Tested-by:` tag** - However, xfstests is mentioned, implying the
fix was tested against this test suite
- **No `Reviewed-by:` tag**
- The commit is from the ntfs3 maintainer (Konstantin Komarov from
Paragon Software)
### 7. DEPENDENCY CHECK
- **No dependencies** - This is a standalone fix
- Uses existing kernel APIs (`div_s64_rem`, `s64`, `s32`) that have been
available for a long time
- The affected code (`nt2kernel` function) has existed since ntfs3 was
introduced in kernel 5.15
### Summary
**YES signals:**
1. ✅ Fixes a **real bug** (incorrect timestamps for pre-epoch dates)
2. ✅ **Small and surgical** change - only 8 lines changed in one
function
3. ✅ **Obviously correct** - uses proper signed arithmetic for values
that can be negative
4. ✅ No new features, no new APIs
5. ✅ Caught by **xfstests**, a standard fs test suite (test 258)
6. ✅ Applies to all stable kernels that have ntfs3 (5.15+)
7. ✅ Zero risk of regression for post-epoch timestamps (mathematically
equivalent)
8. ✅ Fixes **data integrity issue** (timestamp corruption)
**NO signals:**
1. ⚠️ No explicit `Cc: stable@vger.kernel.org` tag
2. ⚠️ No `Fixes:` tag
3. ⚠️ No `Tested-by:` or `Reviewed-by:` tags
**Verdict:**
This is a clear bug fix that addresses a real issue (incorrect pre-epoch
timestamp handling) that affects NTFS3 users. The fix is small,
surgical, uses well-tested kernel APIs, and is mathematically correct.
While the commit lacks stable tags, the nature of the fix - correcting
data integrity issues with timestamps - makes it appropriate for
backporting. The bug has existed since ntfs3 was introduced (5.15), so
all stable trees with ntfs3 would benefit from this fix.
The lack of `Cc: stable` tag is likely an oversight since the fix
clearly meets stable kernel criteria: it's a bug fix, small in scope,
obviously correct, and fixes a real user-visible issue (incorrect file
timestamps).
**YES**
fs/ntfs3/ntfs_fs.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 630128716ea73..2649fbe16669d 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -979,11 +979,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts)
*/
static inline void nt2kernel(const __le64 tm, struct timespec64 *ts)
{
- u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
+ s32 t32;
+ /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */
+ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
- // WARNING: do_div changes its first argument(!)
- ts->tv_nsec = do_div(t, _100ns2seconds) * 100;
- ts->tv_sec = t;
+ ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32);
+ ts->tv_nsec = t32 * 100;
}
static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb)
--
2.51.0
next prev parent reply other threads:[~2025-12-09 0:17 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-09 0:14 [PATCH AUTOSEL 6.18-6.1] ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-6.17] wifi: rtw89: use skb_dequeue() for queued ROC packets to prevent racing Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-6.6] ipv6: clean up routes when manually removing address with a lifetime Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-5.10] ext4: remove page offset calculation in ext4_block_zero_page_range() Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-6.6] fs/ntfs3: fix KMSAN uninit-value in ni_create_attr_list Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-6.6] btrfs: abort transaction on item count overflow in __push_leaf_left() Sasha Levin
2025-12-09 0:14 ` [PATCH AUTOSEL 6.18-6.1] smb/server: fix return value of smb2_ioctl() Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.1] gfs2: Fix use of bio_chain Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] wifi: mac80211: reset CRC valid after CSA Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] Bluetooth: btusb: Add new VID/PID 0x0489/0xE12F for RTL8852BE-VT Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mmio_*_copy fix byte order and alignment Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] btrfs: scrub: always update btrfs_scrub_progress::last_physical Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] bpf: Skip bounds adjustment for conditional jumps on same scalar register Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtl8xxxu: Fix HT40 channel config for RTL8192CU, RTL8723AU Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] Bluetooth: btusb: MT7920: Add VID/PID 0489/e135 Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] Bluetooth: btusb: MT7922: Add VID/PID 0489/e170 Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] virtio_blk: NULL out vqs to avoid double free on failed resume Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.1] kbuild: Use objtree for module signing key path Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.17] btrfs: use kvcalloc for btrfs_bio::csum allocation Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] net: sched: Don't use WARN_ON_ONCE() for -ENOMEM in tcf_classify() Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] hfsplus: Verify inode mode when loading from disk Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.6] gfs2: fix remote evict for read-only filesystems Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] net: amd-xgbe: use EOPNOTSUPP instead of ENOTSUPP in xgbe_phy_mii_read_c45 Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] net: init shinfo->gso_segs from qdisc_pkt_len_init() Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.17] Bluetooth: btusb: add new custom firmwares Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] cxgb4: Rename sched_class to avoid type clash Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] net: mana: Drop TX skb on post_work_request failure and unmap resources Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] hfsplus: fix volume corruption issue for generic/070 Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.17] wifi: rtw89: rtw8852bu: Added dev id for ASUS AX57 NANO USB Wifi dongle Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] net: restore napi_consume_skb()'s NULL-handling Sasha Levin
2025-12-09 0:15 ` Sasha Levin [this message]
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.1] smb/server: fix return value of smb2_query_dir() Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.17] wifi: rtw88: Add BUFFALO WI-U3-866DHP to the USB ID list Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.6] Bluetooth: btusb: Add new VID/PID 2b89/6275 for RTL8761BUV Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] bpf: Disable file_alloc_security hook Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.1] wifi: rtw89: phy: fix out-of-bounds access in rtw89_phy_read_txpwr_limit() Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.6] ntfs: set dummy blocksize to read boot_block when mounting Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-5.10] hfsplus: fix volume corruption issue for generic/073 Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] wifi: mt76: mt792x: fix wifi init fail by setting MCU_RUNNING after CLC load Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.12] gfs2: Fix "gfs2: Switch to wait_event in gfs2_quotad" Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: vfs: fix race on m_flags in vfs_cache Sasha Levin
2025-12-09 0:15 ` [PATCH AUTOSEL 6.18-6.1] wifi: rtw89: flush TX queue before deleting key Sasha Levin
2025-12-09 0:15 ` [Intel-wired-lan] [PATCH AUTOSEL 6.18-6.12] ice: Allow 100M speed for E825C SGMII device Sasha Levin
2025-12-09 0:15 ` Sasha Levin
-- strict thread matches above, loose matches on Subject: below --
2025-12-06 14:02 [PATCH AUTOSEL 6.18-6.1] ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency Sasha Levin
2025-12-06 14:02 ` [PATCH AUTOSEL 6.18-5.15] fs/ntfs3: Support timestamps prior to epoch Sasha Levin
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=20251209001610.611575-33-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=almaz.alexandrovich@paragon-software.com \
--cc=ntfs3@lists.linux.dev \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.