lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <3d517755-3ed1-46eb-9fee-c4e56193ebc4@gmail.com>
Date: Fri, 12 Dec 2025 12:34:10 +0300
From: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@...il.com>
To: clm@...com, dsterba@...e.com
Cc: linux-btrfs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: mtime and ctime is not updated after truncate operation if file
 length was not changed

Detailed description
====================

Last data modification and last file status change timestamps are not 
updated after truncate operation if the file content was not changed 
(truncate length == file length).

ext4 updates both mtime and ctime. But many (if not all?) other file 
systems (btrfs, xfs, nilfs2, f2fs, ???) do not update any timestamps.

The latter behavior seems to violate the POSIX.1-2024 standard. 
Documentation for `truncate()`: “Upon successful completion, truncate() 
shall mark for update the last data modification and last file status 
change timestamps of the file". No special cases described for (not) 
updating timestamps. `ftruncate` behaves as expected though.

Maybe I should also report this to the developers of other file systems.


System info
===========

Linux version 6.18.


How to reproduce
================

```
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
   int status;
   struct stat file_stat;

   status = creat("file", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
   printf("CREAT: %d\n", status);
   close(status);

   status = stat("file", &file_stat);
   printf("STAT: %d\n", status);
   printf("atime=%ld\n", file_stat.st_atim.tv_nsec);
   printf("mtime=%ld\n", file_stat.st_mtim.tv_nsec);
   printf("ctime=%ld\n", file_stat.st_ctim.tv_nsec);

   status = truncate("file", 0);
   printf("TRUNCATE: %d\n", status);

   status = stat("file", &file_stat);
   printf("STAT: %d\n", status);
   printf("atime=%ld\n", file_stat.st_atim.tv_nsec);
   printf("mtime=%ld\n", file_stat.st_mtim.tv_nsec);
   printf("ctime=%ld\n", file_stat.st_ctim.tv_nsec);
}
```

Expected output (ext4):

```
CREAT: 3
STAT: 0
atime=122561651
mtime=122561651
ctime=122561651
TRUNCATE: 0
STAT: 0
atime=122561651
mtime=124063093
ctime=124063093
```

Actual output (Btrfs):

```
CREAT: 3
STAT: 0
atime=502902570
mtime=502902570
ctime=502902570
TRUNCATE: 0
STAT: 0
atime=502902570
mtime=502902570
ctime=502902570
```


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ