refactor(parity): address code-quality review findings
- cli: remove UB in --bwlimit scaling (range-check the double product before casting, drop atoi for the +/-1 form) and add huge/boundary unit tests - test: widen the CI throttle wall-clock band to [1.5, 4.5]s with a 2s cross-tolerance so a loaded runner cannot flake it - log: drop the unused LOG_INFO_BACKUP bit; --info=backup is accepted-but- silent like the other rsync-only categories - client_send: remove the duplicate delete_display_path forward declaration - utils: add non-allocating utils_strip_transfer_root and use it from scanner_note_nonreg and delete_display_path (was duplicated logic) - scanner: lstat() instead of stat() when re-reading an empty dir's metadata - file: drop the no-op else-if and the redundant ELOOP arm in file_ensure_directory_secure (symlinks are refused anyway) - format/stats: document literal_data as whole-file accurate (delta upper bound) instead of claiming literal bytes sent - docs: refresh stale protocol 2.26.0 labels to 2.27.0
This commit is contained in:
+11
-12
@@ -807,23 +807,22 @@ bool file_ensure_directory_secure(const char* path) {
|
||||
} else if (errno == EEXIST) {
|
||||
dir_fd = openat(parent_fd, leaf, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
|
||||
}
|
||||
} else if (dir_fd < 0 && (errno == ENOTDIR || errno == ELOOP)) {
|
||||
/* rsync replaces a destination non-directory (regular file or symlink)
|
||||
with an incoming directory. Confined to the already-opened secure
|
||||
parent fd: the leaf is unlinked by name (never followed) and only a
|
||||
non-directory is ever removed, so this cannot escape the authorized
|
||||
root or remove a pre-existing directory tree. A symlink is left alone:
|
||||
replacing it is not required for FastSync's transferred directories and
|
||||
keeps --keep-dirlinks semantics untouched. */
|
||||
} else if (dir_fd < 0 && errno == ENOTDIR) {
|
||||
/* rsync replaces a destination non-directory (regular file) with an
|
||||
incoming directory. Confined to the already-opened secure parent fd:
|
||||
the leaf is unlinked by name (never followed) and only a non-directory
|
||||
is ever removed, so this cannot escape the authorized root or remove a
|
||||
pre-existing directory tree. A symlink is left alone (openat with
|
||||
O_NOFOLLOW reports ELOOP, which takes no branch here), since replacing
|
||||
it is not required for FastSync's transferred directories and keeps
|
||||
--keep-dirlinks semantics untouched. */
|
||||
struct stat leaf_st;
|
||||
if (fstatat(parent_fd, leaf, &leaf_st, AT_SYMLINK_NOFOLLOW) == 0 && !S_ISDIR(leaf_st.st_mode) &&
|
||||
!S_ISLNK(leaf_st.st_mode)) {
|
||||
if (unlinkat(parent_fd, leaf, 0) == 0) {
|
||||
if (mkdirat(parent_fd, leaf, (mode_t)(0777 & ~(mode_t)file_process_umask())) == 0) {
|
||||
if (mkdirat(parent_fd, leaf, (mode_t)(0777 & ~(mode_t)file_process_umask())) == 0)
|
||||
created = true;
|
||||
} else if (errno != EEXIST) {
|
||||
/* leave dir_fd < 0 so the caller sees the failure */
|
||||
}
|
||||
/* On failure dir_fd stays < 0 below, so the caller still sees it. */
|
||||
dir_fd = openat(parent_fd, leaf, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user