small security-related rsync extension
Dan Stromberg
strombrg at nis.acs.uci.edu
Fri Jun 21 13:30:02 EST 2002
Included below is a shar archive containing two patches that together:
1) make backup files get their setuid and setgid bits stripped by
default
2) add a "-s" option that allows backup files to continue to have
these privileges
This means that if you update a collection of binaries with rsync, and
one or more of them has a local-root security problem, the backup
file(s) created when you fix the problem in your source archive won't
remain exploitable.
The patch is relative to 2.5.4.
The backup-dir support is attempted but untested. We're using the
default backup behavior (with ~) in production. I'd be pleased if
someone who uses backup-dir were to try it out and let me know how it
goes.
I'd also be pleased if this were to find its way into the main
distribution in some form.
Thank you.
#!/bin/sh
# This is a shell archive (shar 3.32)
# made 06/21/2002 20:17 UTC by dcslib at tokyo.acs.uci.edu
# Source directory /dcslibsrc/network/rsync/exportable-patches
#
# existing files WILL be overwritten
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1798 -rw-r--r-- backup-priv-backups
# 1339 -rw-r--r-- options-priv-backups
#
if touch 2>&1 | fgrep 'amc' > /dev/null
then TOUCH=touch
else TOUCH=true
fi
# ============= backup-priv-backups ==============
echo "x - extracting backup-priv-backups (Text)"
sed 's/^X//' << 'SHAR_EOF' > backup-priv-backups &&
X*** backup.c.t Sun May 6 23:59:37 2001
X--- backup.c Fri Jun 21 13:15:51 2002
X***************
X*** 29,34 ****
X--- 29,56 ----
X extern int preserve_devices;
X extern int preserve_links;
X extern int preserve_hard_links;
X+ extern int priv_backups;
X+
X+ #ifdef HAVE_CHMOD
X+ static int strip_perm(char *fname)
X+ {
X+ struct stat buf;
X+ if (link_stat(fname,&buf) != 0) {
X+ rprintf(FERROR,"stat failed\n");
X+ return 0;
X+ }
X+
X+ if (S_ISREG(buf.st_mode) && (buf.st_mode & (S_ISUID | S_ISGID))) {
X+ mode_t new_mode;
X+ new_mode = buf.st_mode & 01777;
X+ if (do_chmod(fname,new_mode) != 0) {
X+ rprintf(FERROR,"chmod failed\n");
X+ return 0;
X+ }
X+ }
X+ return 1;
X+ }
X+ #endif
X
X /* simple backup creates a backup with a suffix in the same directory */
X static int make_simple_backup(char *fname)
X***************
X*** 46,54 ****
X rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
X return 0;
X }
X! } else if (verbose > 1) {
X! rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
X }
X return 1;
X }
X
X--- 68,86 ----
X rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
X return 0;
X }
X! } else {
X! if (verbose > 1) {
X! rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
X! }
X! #ifdef HAVE_CHMOD
X! if (!priv_backups && strip_perm(fnamebak) == 0) {
X! return 0;
X! } else if (verbose > 1) {
X! rprintf(FINFO,"Stripped setuid and/or setgid from %s\n",fnamebak);
X! }
X! #endif
X }
X+
X return 1;
X }
X
X***************
X*** 271,276 ****
X--- 303,314 ----
X fname, keep_name, strerror(errno));
X };
X set_perms (keep_name, file, NULL, 0);
X+ /* may mean an extra stat */
X+ #ifdef HAVE_CHMOD
X+ if (!priv_backups && strip_perm(keep_name) == 0) {
X+ return 0;
X+ }
X+ #endif
X free_file (file);
X free (file);
X
SHAR_EOF
$TOUCH -am 06211315102 backup-priv-backups &&
chmod 0644 backup-priv-backups ||
echo "restore of backup-priv-backups failed"
set `wc -c backup-priv-backups`;Wc_c=$1
if test "$Wc_c" != "1798"; then
echo original size 1798, current size $Wc_c
fi
# ============= options-priv-backups ==============
echo "x - extracting options-priv-backups (Text)"
sed 's/^X//' << 'SHAR_EOF' > options-priv-backups &&
X--- options.c.t Fri Jun 21 08:56:31 2002
X+++ options.c Fri Jun 21 09:41:41 2002
X@@ -21,6 +21,9 @@
X #include "rsync.h"
X #include "popt.h"
X
X+#ifdef HAVE_CHMOD
X+int priv_backups = 0;
X+#endif
X int make_backups = 0;
X int whole_file = -1;
X int copy_links = 0;
X@@ -188,6 +191,7 @@
X rprintf(F," -b, --backup make backups (default %s suffix)\n",BACKUP_SUFFIX);
X rprintf(F," --backup-dir make backups into this directory\n");
X rprintf(F," --suffix=SUFFIX override backup suffix\n");
X+ rprintf(F," --priv-backups preserve set[ug]id on backups\n");
X rprintf(F," -u, --update update only (don't overwrite newer files)\n");
X rprintf(F," -l, --links copy symlinks as symlinks\n");
X rprintf(F," -L, --copy-links copy the referent of symlinks\n");
X@@ -291,6 +295,9 @@
X {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM},
X {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks},
X {"help", 'h', POPT_ARG_NONE, 0, 'h'},
X+#ifdef HAVE_CHMOD
X+ {"priv-backups", 's', POPT_ARG_NONE, &priv_backups},
X+#endif
X {"backup", 'b', POPT_ARG_NONE, &make_backups},
X {"dry-run", 'n', POPT_ARG_NONE, &dry_run},
X {"sparse", 'S', POPT_ARG_NONE, &sparse_files},
SHAR_EOF
$TOUCH -am 06210941102 options-priv-backups &&
chmod 0644 options-priv-backups ||
echo "restore of options-priv-backups failed"
set `wc -c options-priv-backups`;Wc_c=$1
if test "$Wc_c" != "1339"; then
echo original size 1339, current size $Wc_c
fi
exit 0
--
Dan Stromberg UCI/NACS/DCS
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: not available
Url : http://lists.samba.org/archive/rsync/attachments/20020621/307b74d4/attachment.bin
More information about the rsync
mailing list