[Bug 272127] fdescfs with linkrdlnk fails openat with O_DIRECTORY unless "ls -l" done in fdescfs dir first...

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 21 Jun 2023 08:17:09 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=272127

            Bug ID: 272127
           Summary: fdescfs with linkrdlnk fails openat with O_DIRECTORY
                    unless "ls -l" done in fdescfs dir first...
           Product: Base System
           Version: 13.2-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: pen@lysator.liu.se

Seems like the kernel doesn't follow the fdescfs symlink when checking if the
target points to a directory for openat (and open) with the O_DIRECTORY flag. 

Unless you've primed it with an "ls -l" in the directory (or something similar
that does a stat() call). Then it starts to work. To "reset" - unmount and
remount the fdescfs filesystem again

(Thought I was going insane when debugging a problem with Samba 4.18 and Samba
failed but my test program worked. Turned out my test program was doing a
stat() call before attempting this which primed the cache...)


root@runur00:~ # egrep compat /etc/fstab
none            /compat/linux/dev/fd    fdescfs rw,linrdlnk     0       

root@runur00:~ # ./t
./t: openat(AT_FDCWD, "/compat/linux/dev/fd/3", O_DIRECTORY, 0): Not a
directory

root@runur00:~ # ls /compat/linux/dev/fd/
0       1       2       3       4

root@runur00:~ # ./t
./t: openat(AT_FDCWD, "/compat/linux/dev/fd/3", O_DIRECTORY, 0): Not a
directory

root@runur00:~ # ls -l /compat/linux/dev/fd/
total 0
lr-xr-xr-x  1 root  wheel  0 Jun 20 15:57 0 -> /dev/pts/0
lr-xr-xr-x  1 root  wheel  0 Jun 20 15:57 1 -> /dev/pts/0
lr-xr-xr-x  1 root  wheel  0 Jun 20 15:57 2 -> /dev/pts/0
lr-xr-xr-x  1 root  wheel  0 Jun 20 15:57 3 -> /root
lr-xr-xr-x  1 root  wheel  0 Jun 20 15:57 4 -> /etc/spwd.db

root@runur00:~ # ./t
/compat/linux/dev/fd/3: OK

root@runur00:~ # umount /compat/linux/dev/fd
root@runur00:~ # mount /compat/linux/dev/fd

root@runur00:~ # ./t
./t: openat(AT_FDCWD, "/compat/linux/dev/fd/3", O_DIRECTORY, 0): Not a
directory



Test program:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>


int
main(int argc,
     char *argv[]) {
  int dfd, tfd;
  char buf[2048];


  dfd = open(".", O_PATH);

  sprintf(buf, "/compat/linux/dev/fd/%d", dfd);
  tfd = openat(AT_FDCWD, buf, O_DIRECTORY, 0);
  if (tfd < 0) {
    fprintf(stderr, "%s: openat(AT_FDCWD, \"%s\", O_DIRECTORY, 0): %s\n",
argv[0], buf, strerror(errno));
    exit(1);
  }
  printf("%s: OK\n", buf);

  exit(0);
}

-- 
You are receiving this mail because:
You are the assignee for the bug.