[Bug 279570] linuxulator: linux_mkdir returns EACCES instead of EEXIST for mountpoints

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 07 Jun 2024 15:19:53 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279570

            Bug ID: 279570
           Summary: linuxulator: linux_mkdir returns EACCES instead of
                    EEXIST for mountpoints
           Product: Base System
           Version: 14.0-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: kempe@lysator.liu.se

The Linux version of Planescape Torment Enhanced Edition crashed when trying to
save games. I have traced the issue to linux_mkdir returning EACCES instead of
the expected EEXIST when traversing the file system hierarchy.


/bin is a directory on the ZFS root dataset, running mkdir and linux_mkdir
gives the exected behaviour:

~> truss /bin/mkdir /bin &| grep mkdir
mkdir("/bin",0777)                               ERR#17 'File exists'
mkdir: write(2,"mkdir: ",7)                              = 7 (0x7)

~> truss /compat/linux/bin/mkdir /bin &| grep mkdir
linux_mkdir("/bin",511)                          ERR#-17 'File exists'
/compat/linux/bin/mkdir: linux_write(0x2,0x7fffffff96b0,0x19)            = 25
(0x19)

/usr/home is a ZFS dataset mounted on /usr, mounted on the root ZFS dataset. It
gives the unexpected behaviour:

~> truss /bin/mkdir /usr/home &| grep mkdir
mkdir("/usr/home",0777)                          ERR#17 'File exists'
mkdir: write(2,"mkdir: ",7)                              = 7 (0x7)

~> truss /compat/linux/bin/mkdir /usr/home &| grep mkdir
linux_mkdir("/usr/home",511)                     ERR#-13 'Permission denied'
/compat/linux/bin/mkdir: linux_write(0x2,0x7fffffff96b0,0x19)            = 25
(0x19)

As can be seen, FreeBSD mkdir returns file exists as expected, but Linux mkdir
returns permission denied. Setting compat.linux.emul_path=/ and getting mkdir
to work with environment variables makes it have the correct behaviour.

# sysctl compat.linux.emul_path=/
compat.linux.emul_path: /compat/linux -> /
~> env LD_LIBRARY_PATH=/compat/linux/usr/lib64 truss /compat/linux/bin/mkdir
/usr/home &| grep mkdir
linux_mkdir("/usr/home",511)                     ERR#-17 'File exists'
/compat/linux/bin/mkdir: linux_write(0x2,0x7fffffff9680,0x19)            = 25
(0x19)

Indicating that there seems to be an issue with how the file system objects are
being resolved.

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