mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-01-21 13:28:25 -05:00
patches or wrappers. One problem with this is that rsync was not written with this in mind and wasn't very careful about possible stack overflows etc which could lead to security breaches. This wasn't a problem when run in the traditional way as any user that can run rsync can login anyway and cause much more damage that way. This patch attempts to close possible stack overflow problems. I've checked for all strcpy(), strcat(), sprintf() and memcpy() overflows. I would appreciate it if someone else with a devious mind could also go through the rsync source code and see if there are any other stack overflows possible. Let me know if you do.
202 lines
4.2 KiB
C
202 lines
4.2 KiB
C
/*
|
|
Copyright (C) Andrew Tridgell 1996
|
|
Copyright (C) Paul Mackerras 1996
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
/*
|
|
a lot of this stuff was derived from GNU tar
|
|
*/
|
|
|
|
#include "rsync.h"
|
|
|
|
extern int verbose;
|
|
|
|
static char **exclude_list = NULL;
|
|
|
|
static int is_regex(char *str)
|
|
{
|
|
return strchr(str, '*') || strchr(str, '[') || strchr(str, '?');
|
|
}
|
|
|
|
|
|
static int check_one_exclude(char *name,char *pattern)
|
|
{
|
|
char *p;
|
|
|
|
if (!strchr(pattern,'/') && (p=strrchr(name,'/')))
|
|
name = p+1;
|
|
|
|
if (!name[0]) return 0;
|
|
|
|
if (is_regex(pattern)) {
|
|
if (fnmatch(pattern, name, 0) == 0)
|
|
return 1;
|
|
} else {
|
|
int l1 = strlen(name);
|
|
int l2 = strlen(pattern);
|
|
if (l2 <= l1 &&
|
|
strcmp(name+(l1-l2),pattern) == 0 &&
|
|
(l1==l2 || name[l1-(l2+1)] == '/'))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int check_exclude(char *name,char **local_exclude_list)
|
|
{
|
|
int n;
|
|
|
|
if (exclude_list) {
|
|
for (n=0; exclude_list[n]; n++)
|
|
if (check_one_exclude(name,exclude_list[n]))
|
|
return 1;
|
|
}
|
|
|
|
if (local_exclude_list) {
|
|
for (n=0; local_exclude_list[n]; n++)
|
|
if (check_one_exclude(name,local_exclude_list[n]))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void add_exclude_list(char *pattern,char ***list)
|
|
{
|
|
int len=0;
|
|
if (list && *list)
|
|
for (; (*list)[len]; len++) ;
|
|
|
|
if (strcmp(pattern,"!") == 0) {
|
|
if (verbose > 2)
|
|
fprintf(FERROR,"clearing exclude list\n");
|
|
while ((len)--)
|
|
free((*list)[len]);
|
|
free((*list));
|
|
*list = NULL;
|
|
return;
|
|
}
|
|
|
|
if (!*list) {
|
|
*list = (char **)malloc(sizeof(char *)*2);
|
|
} else {
|
|
*list = (char **)realloc(*list,sizeof(char *)*(len+2));
|
|
}
|
|
|
|
if (!*list || !((*list)[len] = strdup(pattern)))
|
|
out_of_memory("add_exclude");
|
|
|
|
if (verbose > 2)
|
|
fprintf(FERROR,"add_exclude(%s)\n",pattern);
|
|
|
|
(*list)[len+1] = NULL;
|
|
}
|
|
|
|
void add_exclude(char *pattern)
|
|
{
|
|
add_exclude_list(pattern,&exclude_list);
|
|
}
|
|
|
|
char **make_exclude_list(char *fname,char **list1,int fatal)
|
|
{
|
|
char **list=list1;
|
|
FILE *f = fopen(fname,"r");
|
|
char line[MAXPATHLEN];
|
|
if (!f) {
|
|
if (fatal) {
|
|
fprintf(FERROR,"%s : %s\n",fname,strerror(errno));
|
|
exit_cleanup(1);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
while (fgets(line,MAXPATHLEN,f)) {
|
|
int l = strlen(line);
|
|
if (l && line[l-1] == '\n') l--;
|
|
line[l] = 0;
|
|
if (line[0]) add_exclude_list(line,&list);
|
|
}
|
|
fclose(f);
|
|
return list;
|
|
}
|
|
|
|
|
|
void add_exclude_file(char *fname,int fatal)
|
|
{
|
|
exclude_list = make_exclude_list(fname,exclude_list,fatal);
|
|
}
|
|
|
|
|
|
void send_exclude_list(int f)
|
|
{
|
|
int i;
|
|
if (exclude_list)
|
|
for (i=0;exclude_list[i];i++) {
|
|
int l = strlen(exclude_list[i]);
|
|
if (l == 0) continue;
|
|
write_int(f,l);
|
|
write_buf(f,exclude_list[i],l);
|
|
}
|
|
write_int(f,0);
|
|
}
|
|
|
|
|
|
void recv_exclude_list(int f)
|
|
{
|
|
char line[MAXPATHLEN];
|
|
int l;
|
|
while ((l=read_int(f))) {
|
|
read_buf(f,line,l);
|
|
line[l] = 0;
|
|
add_exclude(line);
|
|
}
|
|
}
|
|
|
|
|
|
static char *cvs_ignore_list[] = {
|
|
"RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
|
|
"tags","TAGS",".make.state",".nse_depinfo",
|
|
"*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig",
|
|
"*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln",
|
|
"core",NULL};
|
|
|
|
|
|
|
|
void add_cvs_excludes(void)
|
|
{
|
|
char fname[MAXPATHLEN];
|
|
char *p;
|
|
int i;
|
|
|
|
for (i=0; cvs_ignore_list[i]; i++)
|
|
add_exclude(cvs_ignore_list[i]);
|
|
|
|
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
|
|
sprintf(fname,"%s/.cvsignore",p);
|
|
add_exclude_file(fname,0);
|
|
}
|
|
|
|
if ((p=getenv("CVSIGNORE"))) {
|
|
char *tok;
|
|
for (tok=strtok(p," "); tok; tok=strtok(NULL," "))
|
|
add_exclude(tok);
|
|
}
|
|
}
|