Whamcloud - gitweb
LU-2302 scripts: prevent lfs_migrate data disclosure
[fs/lustre-release.git] / lustre / scripts / lfs_migrate
old mode 100644 (file)
new mode 100755 (executable)
index 969386e..c285510
@@ -20,7 +20,7 @@ LFS=${LFS:-lfs}
 
 usage() {
     cat -- <<USAGE 1>&2
-usage: lfs_migrate [-c <stripe_count>] [-h] [-l] [-n] [-q] [-R] [-s] [-y]
+usage: lfs_migrate [-c <stripe_count>] [-h] [-l] [-n] [-q] [-R] [-s] [-y] [-0]
                    [file|dir ...]
     -c <stripe_count>
        restripe file using the specified stripe count
@@ -31,6 +31,7 @@ usage: lfs_migrate [-c <stripe_count>] [-h] [-l] [-n] [-q] [-R] [-s] [-y]
     -R restripe file using default directory striping
     -s skip file data comparison after migrate
     -y answer 'y' to usage question
+    -0 input file names on stdin are separated by a null character
 
 The -c <stripe_count> option may not be specified at the same time as
 the -R option.
@@ -47,7 +48,7 @@ USAGE
 OPT_CHECK=y
 OPT_STRIPE_COUNT=""
 
-while getopts "c:hlnqRsy" opt $*; do
+while getopts "c:hlnqRsy0" opt $*; do
     case $opt in
        c) OPT_STRIPE_COUNT=$OPTARG;;
        l) OPT_NLINK=y;;
@@ -56,6 +57,7 @@ while getopts "c:hlnqRsy" opt $*; do
        R) OPT_RESTRIPE=y;;
        s) OPT_CHECK="";;
        y) OPT_YES=y;;
+       0) OPT_NULL=y;;
        h|\?) usage;;
     esac
 done
@@ -88,12 +90,18 @@ $RSYNC --help 2>&1 | grep -q acls && RSYNC_OPTS="$RSYNC_OPTS -A"
 # If rsync copies lustre xattrs in the future, then we can skip lfs (bug 22189)
 strings $(which $RSYNC) 2>&1 | grep -q lustre && LFS=:
 
+# rsync creates its temporary files with lenient permissions, even if
+# permissions on the original files are more strict. Tighten umask here
+# to avoid the brief window where unprivileged users might be able to
+# access the temporary file.
+umask 0077
+
 lfs_migrate() {
-       while read OLDNAME; do
+       while IFS='' read -d '' OLDNAME; do
                $ECHO -n "$OLDNAME: "
 
                # avoid duplicate stat if possible
-               TYPE_LINK=($(stat -c "%h %F" "$OLDNAME" || true))
+               TYPE_LINK=($(LANG=C stat -c "%h %F" "$OLDNAME" || true))
 
                # skip non-regular files, since they don't have any objects
                # and there is no point in trying to migrate them.
@@ -163,13 +171,17 @@ lfs_migrate() {
 }
 
 if [ "$#" -eq 0 ]; then
-       lfs_migrate
+       if [ "$OPT_NULL" ]; then
+               lfs_migrate
+       else
+               tr '\n' '\0' | lfs_migrate
+       fi
 else
        while [ "$1" ]; do
                if [ -d "$1" ]; then
-                       lfs find "$1" -type f | lfs_migrate
+                       lfs find "$1" -type f -print0 | lfs_migrate
                else
-                       echo $1 | lfs_migrate
+                       echo -en "$1\0" | lfs_migrate
                fi
                shift
        done