mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-20 04:51:58 -04:00
use mkstemp on systems where it is secure
This commit is contained in:
1 parent
0f62178580
commit
f62c17e378
6 files changed
+57
-27
No files matched your search
+2
-5
@@ -54,17 +54,14 @@ install-strip:
|
||||
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
|
||||
|
||||
rsync: $(OBJS)
|
||||
@-echo " Note: The link command may give a warning about use of mktemp."
|
||||
@-echo " The warning may be ignored because rsync uses this function in a safe way."
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
|
||||
Makefile: Makefile.in configure config.status
|
||||
echo "WARNING: You need to run ./config.status --recheck"
|
||||
|
||||
# It's OK if this fails, because we don't require people to have
|
||||
# autoconf installed.
|
||||
# don't actually run autoconf, just issue a warning
|
||||
configure: configure.in
|
||||
-cd $(srcdir) && autoconf
|
||||
echo "WARNING: you need to rerun autoconf"
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
#undef REPLACE_INET_ATON
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef HAVE_SOCKETPAIR
|
||||
#undef HAVE_SECURE_MKSTEMP
|
||||
@@ -231,6 +231,28 @@ if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
|
||||
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for secure mkstemp],rsync_cv_HAVE_SECURE_MKSTEMP,[
|
||||
AC_TRY_RUN([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
main() {
|
||||
struct stat st;
|
||||
char tpl[20]="/tmp/test.XXXXXX";
|
||||
int fd = mkstemp(tpl);
|
||||
if (fd == -1) exit(1);
|
||||
unlink(tpl);
|
||||
if (fstat(fd, &st) != 0) exit(1);
|
||||
if ((st.st_mode & 0777) != 0600) exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=yes,
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=no,
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=cross)])
|
||||
if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SECURE_MKSTEMP)
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
|
||||
AC_TRY_RUN([
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
size_t ret = len;
|
||||
if (bufsize <= 0) return 0;
|
||||
if (len >= bufsize) len = bufsize-1;
|
||||
memcpy(d, s, len);
|
||||
d[len] = 0;
|
||||
|
||||
+11
-15
@@ -304,6 +304,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
int fd1,fd2;
|
||||
STRUCT_STAT st;
|
||||
char *fname;
|
||||
char template[MAXPATHLEN];
|
||||
char fnametmp[MAXPATHLEN];
|
||||
char *fnamecmp;
|
||||
char fnamecmpbuf[MAXPATHLEN];
|
||||
@@ -412,17 +413,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* mktemp is deliberately used here instead of mkstemp.
|
||||
because O_EXCL is used on the open, the race condition
|
||||
is not a problem or a security hole, and we want to
|
||||
control the access permissions on the created file. */
|
||||
if (NULL == do_mktemp(fnametmp)) {
|
||||
rprintf(FERROR,"mktemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
continue;
|
||||
}
|
||||
strlcpy(template, fnametmp, sizeof(template));
|
||||
|
||||
/* we initially set the perms without the
|
||||
setuid/setgid bits to ensure that there is no race
|
||||
@@ -430,16 +421,21 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
the lchown. Thanks to snabb@epipe.fi for pointing
|
||||
this out. We also set it initially without group
|
||||
access because of a similar race condition. */
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & INITACCESSPERMS);
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"mkstemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* in most cases parent directories will already exist
|
||||
because their information should have been previously
|
||||
transferred, but that may not be the case with -R */
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & INITACCESSPERMS);
|
||||
strlcpy(fnametmp, template, sizeof(fnametmp));
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
|
||||
|
||||
@@ -113,14 +113,27 @@ int do_mkdir(char *fname, mode_t mode)
|
||||
return mkdir(fname, mode);
|
||||
}
|
||||
|
||||
char *do_mktemp(char *template)
|
||||
/* like mkstemp but forces permissions */
|
||||
int do_mkstemp(char *template, mode_t perms)
|
||||
{
|
||||
if (dry_run) return NULL;
|
||||
if (read_only) {errno = EROFS; return NULL;}
|
||||
|
||||
/* TODO: Replace this with a good builtin mkstemp, perhaps
|
||||
* from OpenBSD. Some glibc versions are buggy. */
|
||||
return mktemp(template);
|
||||
if (dry_run) return -1;
|
||||
if (read_only) {errno = EROFS; return -1;}
|
||||
|
||||
#if defined(HAVE_SECURE_MKSTEMP) && defined(HAVE_FCHMOD)
|
||||
{
|
||||
int fd = mkstemp(template);
|
||||
if (fd == -1) return -1;
|
||||
if (fchmod(fd, perms) != 0) {
|
||||
close(fd);
|
||||
unlink(template);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
#else
|
||||
if (!mktemp(template)) return -1;
|
||||
return open(template, O_RDWR|O_EXCL|O_CREAT, perms);
|
||||
#endif
|
||||
}
|
||||
|
||||
int do_stat(const char *fname, STRUCT_STAT *st)
|
||||
|
||||
Reference in new issue
Block a user