From: Wayne Davison Date: Fri, 5 May 2006 05:55:40 +0000 (+0000) Subject: Added a new function named die_on_unsafe_path(). This is used X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/commitdiff_plain/f47807900b528fc89dfb0d331f98be627ff67429 Added a new function named die_on_unsafe_path(). This is used by a non-chroot daemon to ensure that a user-supplied path does not contain an unsafe symlink element. --- diff --git a/util.c b/util.c index 875af11e..337aa83f 100644 --- a/util.c +++ b/util.c @@ -900,6 +900,46 @@ int safe_stat(const char *fname, STRUCT_STAT *stp) #endif } +void die_on_unsafe_path(char *path, int strip_filename) +{ +#ifdef SUPPORT_LINKS + char *final_slash, *p; + STRUCT_STAT st; + + if (!path) + return; + if (strip_filename) { + if (!(final_slash = strrchr(path, '/'))) + return; + *final_slash = '\0'; + } else + final_slash = NULL; + + p = path; + if (*p == '/') + p += module_dirlen + 1; + while (*p) { + if ((p = strchr(p, '/')) != NULL) + *p = '\0'; + if (safe_stat(path, &st) < 0) { + *p++ = '/'; + goto done; + } + if (S_ISLNK(st.st_mode)) { + rprintf(FERROR, "Unsafe path: %s\n", path); + exit_cleanup(RERR_SYNTAX); + } + if (!p) + break; + *p++ = '/'; + } + + done: + if (final_slash) + *final_slash = '/'; +#endif +} + /* Like chdir(), but it keeps track of the current directory (in the * global "curr_dir"), and ensures that the path size doesn't overflow. * Also cleans the path using the clean_fname() function. */