Re: futimens use of utimensat does not support O_PATH fds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2025-08-07, Josh Triplett <josh@xxxxxxxxxxxxxxxx> wrote:
> I just discovered that opening a file with O_PATH gives an fd that works
> with
> 
> utimensat(fd, "", times, O_EMPTY_PATH)

I guess you mean AT_EMPTY_PATH? We don't have O_EMPTY_PATH on Linux
(yet, at least...).

> but does *not* work with what futimens calls, which is:
> 
> utimensat(fd, NULL, times, 0)
> 
> The former will go through do_utimes_fd, while the latter goes through
> do_utimes_path. I would have expected these two cases to end up in the
> same codepath once they'd discovered they were operating on a file
> descriptor, and I would have expected both to support O_PATH file
> descriptors if either does.
> 
> This is true for both symlinks (with O_NOFOLLOW | O_PATH) and regular
> files (with just O_PATH). This is on 6.12, in case it matters.
> 
> Quick and dirty test program (in Rust, using rustix to make syscalls):
> 
> ```
> use rustix::fs::{AtFlags, OFlags, Timespec, Timestamps, UTIME_OMIT};
> 
> fn main() -> std::io::Result<()> {
>     let f = rustix::fs::open("oldfile", OFlags::PATH | OFlags::CLOEXEC, 0o666.into())?;
>     let times = Timestamps {
>         last_access: Timespec { tv_sec: 0, tv_nsec: UTIME_OMIT },
>         last_modification: Timespec { tv_sec: 0, tv_nsec: 0 },
>     };
>     let ret = rustix::fs::utimensat(&f, "", &times, AtFlags::EMPTY_PATH);
>     println!("utimensat: {ret:?}");
>     let ret = rustix::fs::futimens(&f, &times);
>     println!("futimens: {ret:?}");
>     Ok(())
> }
> ```
> 
> Is this something that would be reasonable to fix? Would a patch be
> welcome that makes both cases work identically and support O_PATH file
> descriptors?

The set of things that are and are not allowed on O_PATH file
descriptors is a bit of a hodge-podge these days. Originally the
intention was for all of these things to be blocked by O_PATH (kind of
like O_SEARCH on other *nix systems) but the existence of AT_EMPTY_PATH
(and /proc/self/fd/... hackery) slowly led more and more things to be
allowed.

The current stalemate is that stuff which operates on the fd directly
(fchmod/fchown) tends to not allow operations on O_PATH file
descriptors, while stuff that operates on paths with AT_EMPTY_PATH
(fchmodat/fchownat) does. Why? My impression is that this is mainly
because the man-page (and the original descriptions by Al) says that the
former set of functions don't work on O_PATH. (Though Al probably has a
different viewpoint.)

I was working on an attempted solution for this mess (as part of work to
add O_EMPTY_PATH support while also plugging some holes in the
re-opening semantics on Linux), but it's on the backburner for now.
The core issue is that O_PATH is a very minimalistic capability system,
and different users expect different things from O_PATH, and there isn't
a nice way to make everyone happy with just one bit.

-- 
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH
https://www.cyphar.com/

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux