X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/43b06eeae9f654e812cc9d4a5237450172965ad3..b41c3f92738709adf79a1d77f8e7e75752bd1adf:/util.c diff --git a/util.c b/util.c index 15ab69d2..6e0fbaba 100644 --- a/util.c +++ b/util.c @@ -98,6 +98,9 @@ int piped_child(char **command,int *f_in,int *f_out) *f_in = from_child_pipe[0]; *f_out = to_child_pipe[1]; + + set_nonblocking(*f_in); + set_nonblocking(*f_out); return pid; } @@ -250,7 +253,7 @@ static int full_write(int desc, char *ptr, int len) for an error. derived from GNU C's cccp.c. */ -int safe_read(int desc, char *ptr, int len) +static int safe_read(int desc, char *ptr, int len) { int n_chars; @@ -291,7 +294,7 @@ int copy_file(char *source, char *dest, mode_t mode) } ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode); - if (ofd < 0) { + if (ofd == -1) { rprintf(FERROR,"open %s: %s\n", dest,strerror(errno)); close(ifd); @@ -407,14 +410,6 @@ int name_to_gid(char *name, gid_t *gid) } -/**************************************************************************** -check if a process exists. -****************************************************************************/ -int process_exists(int pid) -{ - return(kill(pid,0) == 0 || errno != ESRCH); -} - /* lock a byte range in a open file */ int lock_range(int fd, int offset, int len) { @@ -432,7 +427,7 @@ int lock_range(int fd, int offset, int len) static void glob_expand_one(char *s, char **argv, int *argc, int maxargs) { -#ifndef HAVE_GLOB +#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H)) if (!*s) s = "."; argv[*argc] = strdup(s); (*argc)++; @@ -710,3 +705,50 @@ void show_progress(OFF_T ofs, OFF_T size) } } } + +/* determine if a symlink points outside the current directory tree */ +int unsafe_symlink(char *dest, char *src) +{ + char *tok; + int depth = 0; + + /* all absolute and null symlinks are unsafe */ + if (!dest || !(*dest) || (*dest == '/')) return 1; + + src = strdup(src); + if (!src) out_of_memory("unsafe_symlink"); + + /* find out what our safety margin is */ + for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) { + if (strcmp(tok,"..") == 0) { + depth=0; + } else if (strcmp(tok,".") == 0) { + /* nothing */ + } else { + depth++; + } + } + free(src); + + /* drop by one to account for the filename portion */ + depth--; + + dest = strdup(dest); + if (!dest) out_of_memory("unsafe_symlink"); + + for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) { + if (strcmp(tok,"..") == 0) { + depth--; + } else if (strcmp(tok,".") == 0) { + /* nothing */ + } else { + depth++; + } + /* if at any point we go outside the current directory then + stop - it is unsafe */ + if (depth < 0) break; + } + + free(dest); + return (depth < 0); +}