Re: [RFC PATCH v2 1/2] vfs: syscalls: add mkdirat2() that returns an O_DIRECTORY fd
From: Mateusz Guzik <hidden>
Date: 2026-04-27 16:30:57
Also in:
linux-arch, linux-fsdevel, lkml
On Mon, Apr 27, 2026 at 5:14 PM Christian Brauner [off-list ref] wrote:
quoted
Things proceed to handle_truncate: int error = get_write_access(inode); if (error) return error; error = security_file_truncate(filp); if (!error) { error = do_truncate(idmap, path->dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, filp); } I'm going to ignore the LSM situation and do_truncate failure modes in this one. AFAICS nothing prevents the same user from racing against file creation to execve it, which starts with exe_file_deny_write_access. Should the other thread win the race, get_write_access will fail and the WARN_ON splat will be generated. That is definitely a problem.That can't happen: static inline int get_write_access(struct inode *inode) { return atomic_inc_unless_negative(&inode->i_writecount) ? 0 : -ETXTBSY; } and the check is: error = handle_truncate(idmap, file); if (unlikely(error > 0)) { This was a catch all for broken LSM hook or ->open() instance.
So with this prog:
#include <fcntl.h>
int main(void)
{
open("test", O_TRUNC);
}
I verified writecount is 0 on entry to handle_truncate like so:
bpftrace -e 'kprobe:security_file_truncate { @[comm, (int64)((struct
file *)arg0)->f_path.dentry->d_inode->i_writecount.counter] = count();
}'
@[a.out, 1]: 1
i.e., get_write_access in handle_truncate transitioned the count 0 -> 1
but then what prevents the following race:
CPU0 CPU1
open("test") execve("test")
handle_truncate do_open_execat
exe_file_deny_write_access # should
succeed as count is 0?
get_write_access # should fail as the count is now -1?