diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-01-03 17:17:35 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-01-04 14:42:36 -0500 |
commit | 45fb1d952c3b262278a3b22e9c7d60cca19a5407 (patch) | |
tree | 500f3e4d2288c427669c9fe62dafac64d6e53533 /src/bftw.c | |
parent | d874481987c381fd572a6f3c43840c50111a9554 (diff) | |
download | bfs-45fb1d952c3b262278a3b22e9c7d60cca19a5407.tar.xz |
Work around DragonFly BSD kernel bug
DragonFly's x86_64 assembly implementation of copyinstr() checks the
wrong pointer when deciding whether to return EFAULT or ENAMETOOLONG,
causing it to always return EFAULT for overlong paths. Work around it
by treating EFAULT the same as ENAMETOOLONG on DragonFly.
Link: https://twitter.com/tavianator/status/1742991411203485713
Diffstat (limited to 'src/bftw.c')
-rw-r--r-- | src/bftw.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -739,10 +739,22 @@ static int bftw_file_open(struct bftw_state *state, struct bftw_file *file, cons } int fd = bftw_file_openat(state, file, base, at_path); - if (fd >= 0 || errno != ENAMETOOLONG) { + if (fd >= 0) { return fd; } + switch (errno) { + case ENAMETOOLONG: +#if __DragonFly__ + // https://twitter.com/tavianator/status/1742991411203485713 + case EFAULT: +#endif + break; + + default: + return -1; + } + // Handle ENAMETOOLONG by manually traversing the path component-by-component struct bftw_list parents; SLIST_INIT(&parents); |