ish icon indicating copy to clipboard operation
ish copied to clipboard

Handle AT_EMPTY_PATH for fstatat64

Open zhaofengli opened this issue 2 years ago • 6 comments

This PR adds correct handling for the AT_EMPTY_PATH flag in fstatat64. AT_EMPTY_PATH allows an empty string to be specified as the path, in which case fstatat should operate on the file pointed at by the fd itself:

       AT_EMPTY_PATH (since Linux 2.6.39)
              If pathname is an empty string, operate on the file
              referred to by dirfd (which may have been obtained using
              the open(2) O_PATH flag).  In this case, dirfd can refer
              to any type of file, not just a directory, and the
              behavior of fstatat() is similar to that of fstat().  If
              dirfd is AT_FDCWD, the call operates on the current
              working directory.  This flag is Linux-specific; define
              _GNU_SOURCE to obtain its definition.

This behavior is relied on by newer glibc when loading shared objects. Currently we return -ENOENT for empty paths, leading to behavior like:

/ # bash
bash: error while loading shared libraries: libreadline.so.8: cannot stat shared object: No such file or directory
/ # dmesg
[snip]
2 call 295 openat(-100, "/nix/store/kslb3am4237in6m7i6qi210vc6w7rsfn-readline-8.1p2/lib/libreadline.so.8", 0x88000, 0x0) = 0x3
2 call 3   read(3, 0xffffd110, 512) "ELF" = 0x200
2 call 180 pread(3, 0xffffcee0, 40, 314308) "" = 0x28
2 call 300 stat(at=3, path="", statbuf=0xffffce78, follow_links=1) = 0xfffffffe
2 call 6   close(3) = 0x0
2 call 146 writev(2, 0xffffcd90, 10) {"bash", 4} {": ", 2} {"error while loading shared libraries", 36} {": ", 2} {"libreadline.so.8", 16} {": ", 2} {"cannot stat shared object", 25} {": ", 2} {"No such file or directory", 25} {"
", 1} = 0x73
2 call 252 exit_group(127)

With the fix:

/ # bash
bash-5.1# exit
/ # dmesg
[snip]
4 call 295 openat(-100, "/nix/store/kslb3am4237in6m7i6qi210vc6w7rsfn-readline-8.1p2/lib/libreadline.so.8", 0x88000, 0x0) = 0x3
4 call 3   read(3, 0xffffd110, 512) "ELF" = 0x200
4 call 180 pread(3, 0xffffcee0, 40, 314308) "" = 0x28
4 call 300 stat(at=3, path="", statbuf=0xffffce78, flags=0x1000) = 0x0

Note that many glibc programs are still broken. I'm playing around with getting a Nix-based environment running in iSH and while I was able to start bash and run some small programs, Nix itself still doesn't run:

  • getcontext() and setcontext() save and restore fs (#370)
    • 5 illegal instruction at 0xf749e35f: 66 8c e2 89 50 18 8d 88 (mov dx, fs)
  • Need to implement/stub more syscalls: 126 (sigprocmask), 435 (clone3)
  • ... and more, because Nix still hangs after some quick hacks

zhaofengli avatar May 24 '22 22:05 zhaofengli

Thank

pinneno avatar Jun 02 '22 07:06 pinneno

Thk

pinneno avatar Jun 02 '22 10:06 pinneno

zhaofengli:fstat-empty-path

pinneno avatar Jun 02 '22 10:06 pinneno

@emkey1 I just tried the latest AOK release on TestFlight and it doesn't appear to have my PR. I think you merged the master branch in my fork which is not the PR.

zhaofengli avatar Jun 12 '22 07:06 zhaofengli

@emkey1 I just tried the latest AOK release on TestFlight and it doesn't appear to have my PR. I think you merged the master branch in my fork which is not the PR.

Thank you for the heads up and sorry about that. I’ll take a look in a bit.

emkey1 avatar Jun 12 '22 13:06 emkey1

nix on iSH? 👀

yassernasc avatar Jun 22 '23 12:06 yassernasc