copy_file.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) Index: libbb/copy_file.c =================================================================== --- libbb/copy_file.c (revision 2446) +++ libbb/copy_file.c (working copy) @@ -83,6 +83,7 @@ int copy_file(const char *source, const if (S_ISDIR(source_stat.st_mode)) { DIR *dp; struct dirent *d; + char *existing_name; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { @@ -112,6 +113,20 @@ int copy_file(const char *source, const } umask(saved_umask); + + if (lstat(dest, &dest_stat) < 0) + { + bb_perror_msg("cannot stat '%s'", dest); + return -1; + } + } + + if (is_in_ino_dev_hashtable(&source_stat, &existing_name)) + { + /* source can't be a parent of dest. */ + bb_error_msg("cannot copy a directory, `%s', into itself, `%s'", + existing_name, dest); + return -1; } /* Recursively copy files in SOURCE. */ @@ -127,6 +142,10 @@ int copy_file(const char *source, const new_source = concat_subpath_file(source, d->d_name); if (new_source == NULL) continue; + + /* no component of dest must ever be found in source */ + add_to_ino_dev_hashtable(&dest_stat, new_source); + new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags) < 0) status = -1;