[libc++] Fix UB in filesystem::__copy for non-existent destination. (#87615)
The lstat/stat/fstat functions have no guarantee whether the `struct stat` buffer is changed or not on failure. The filesystem::__copy function assumes that the `struct stat` buffer is not updated on failure, which is not necessarily correct. It appears that for a non-existing destination `detail::posix_lstat(to, t_st, &m_ec1)` returns a failure indicator and overwrites the `struct stat` buffer with a garbage value, which is accidentally equal to the `f_st` from stack internals from the previous `detail::posix_lstat(from, f_st, &m_ec1)` call. file_type::not_found is a known status, so checking against `if (not status_known(t))` passes spuriously and execution continues. Then the __copy function returns errc::function_not_supported because stats are accidentally equivalent, which is incorrect. Before checking for `detail::stat_equivalent`, we instead need to make sure that the call to lstat/stat/fstat was successful. As a result of `f_st` and `t_st` not being accessed anymore without checking for the lstat/stat/fstat success indicator, it is not needed to zero-initialize them.
parent
0c5319e5
Please register or sign in to comment