Bug 198570

Summary: Add fnctl(F_GETPATH) support to FreeBSD
Product: Base System Reporter: Niall Douglas <s_bugzilla>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: New ---    
Severity: Affects Some People CC: crest, emaste, eto.freebsd, girivs82, pjfloyd, val
Priority: --- Keywords: feature
Version: CURRENT   
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197695
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197778

Description Niall Douglas 2015-03-13 20:58:53 UTC
Related: #197695 (Fix broken KERN_PROC_FILEDESC sysctl), #197778 (Implement the AT_EMPTY_PATH race free Linux extension).

The lack of a facility to fetch the current path of an open file descriptor prevents race free filesystem code. For example, right now there is no reliable way of opening a fd to the containing directory of an open file handle, and therefore there is no way of unlinking, renaming or hard linking a file which has been relocated by a third party since it was opened.

Ideally FreeBSD ought to provide direct fd file operations (#197778), but even with a full suite of those there remains one occasion when you really must have the full path for an open fd: when you are symlinking from somewhere to wherever that fd references on the filing system.

What is annoying is that this is straightforward on Windows especially, and with a bit of work on Linux. On OS X F_GETPATH is unstable with respect to hard links, so it returns any of the hard links to a fd, and it's somewhat random which you get.

Would there be any appetite for FreeBSD to gain a F_GETPATH fnctl?

char buffer[4096];
int len;
if(-1==(len=fnctl(fd, F_GETPATH, buffer, sizeof(buffer))))
  errno might be EBADF, EOVERFLOW;
buffer[0...len] contains the zero terminated path of the hard link originally opened as the fd which is a null string if that hard link has been deleted.

This would bring to FreeBSD semantic equivalence to Linux and Windows. And not replicate the broken F_GETPATH in OS X.

Niall
Comment 1 Martin eto Misuth 2016-08-24 12:28:33 UTC
Although it probably doesn't make any difference, I would like to vote for this cause as well.
Comment 2 Shankar Giri 2017-06-04 04:49:05 UTC
FWIW +1 for me to vote for this as well.
Comment 3 Val Packett 2021-10-10 12:30:04 UTC
Now we do have O_PATH with corresponding operations (bug 197778) but so far I've found a few reasons to "getpath" on these when working on xdg-document-portal:

- extattr_set_fd/extattr_delete_fd don't work with O_PATH, returning EBADFD (there's no space for an AT_EMPTY_PATH type flag in the API but maybe they should Just Work since these aren't *at calls, I'll try to patch this probably)
- linkat(AT_EMPTY_PATH) requires root privileges!? (was there no better, less restrictive way to deal with the security issues?)
- sometimes the program literally just needs to read the damn path to return to somewhere

Now, I wonder if KERN_PROC_FILEDESC is guaranteed to be reliable on O_PATH descriptors?

(Wait, do we even have the "broken filedesc" problem anymore? We do have fdescfs with the linrdlnk mount option, which basically provides the Linux style symlink API, and it's not "debugging only"!)
Comment 4 Paul Floyd 2023-05-09 06:41:36 UTC
Another +1

I'd really like a simple and reliable mechanism for Valgrind, which is supposed to be able to track fds. 

At the moment it seems that we have the choice between syscl kern.proc.filedesc which is very clunky for resolving a single fd, and unreliable. 

We also have

fcntl(fd, F_KINFO, kinfo_file*)

which is again unreliable.