Re: [PATCH RFC 1/2] fcntl: add F_CREATED

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

 



On Wed, Jul 24, 2024 at 09:56:09AM GMT, Jeff Layton wrote:
> On Wed, 2024-07-24 at 15:15 +0200, Christian Brauner wrote:
> > Systemd has a helper called openat_report_new() that returns whether a
> > file was created anew or it already existed before for cases where
> > O_CREAT has to be used without O_EXCL (cf. [1]). That apparently isn't
> > something that's specific to systemd but it's where I noticed it.
> > 
> > The current logic is that it first attempts to open the file without
> > O_CREAT | O_EXCL and if it gets ENOENT the helper tries again with both
> > flags. If that succeeds all is well. If it now reports EEXIST it
> > retries.
> > 
> > That works fairly well but some corner cases make this more involved. If
> > this operates on a dangling symlink the first openat() without O_CREAT |
> > O_EXCL will return ENOENT but the second openat() with O_CREAT | O_EXCL
> > will fail with EEXIST. The reason is that openat() without O_CREAT |
> > O_EXCL follows the symlink while O_CREAT | O_EXCL doesn't for security
> > reasons. So it's not something we can really change unless we add an
> > explicit opt-in via O_FOLLOW which seems really ugly.
> > 
> > The caller could try and use fanotify() to register to listen for
> > creation events in the directory before calling openat(). The caller
> > could then compare the returned tid to its own tid to ensure that even
> > in threaded environments it actually created the file. That might work
> > but is a lot of work for something that should be fairly simple and I'm
> > uncertain about it's reliability.
> > 
> > The caller could use a bpf lsm hook to hook into security_file_open() to
> > figure out whether they created the file. That also seems a bit wild.
> > 
> > So let's add F_CREATED which allows the caller to check whether they
> > actually did create the file. That has caveats of course but I don't
> > think they are problematic:
> > 
> > * In multi-threaded environments a thread can only be sure that it did
> >   create the file if it calls openat() with O_CREAT. In other words,
> >   it's obviously not enough to just go through it's fdtable and check
> >   these fds because another thread could've created the file.
> > 
> 
> Not exactly. FMODE_CREATED is set in the file description. In principle
> a userland program should know which thread actually did the the open()
> that results in each fd. This new interface tells us which fd's open
> actually resulted in the file being created (which is good).
> 
> In any case, I don't see this as a problem. The interface does what it
> says on the tin.
> 
> > * If there's any codepaths where an openat() with O_CREAT would yield
> >   the same struct file as that of another thread it would obviously
> >   cause wrong results. I'm not aware of any such codepaths from openat()
> >   itself. Imho, that would be a bug.
> > 
> 
> Definitely a bug. That said, this will have interesting interactions
> with dup that may need to be documented. IOW, if you dup a file with
> FMODE_CREATED, then the new fd will also report that F_CREATED is true.

Yes, but it's the behavior one expects. Dup'ing an fd implies fd1->file
== fd2->file and so it's correct behavior. IOW, someone must confuse
open() with dup() to be surprised by this.




[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