Fix nasty bug in chmod, plus minor fixes.
authorSteve Youngs <steve@sxemacs.org>
Wed, 12 Mar 2014 04:05:17 +0000 (14:05 +1000)
committerSteve Youngs <steve@sxemacs.org>
Wed, 12 Mar 2014 04:05:17 +0000 (14:05 +1000)
* usr/lib/pkgusr/chmod: My idea for converting symbolic chmods
into numeric was completely wrong.  Rewrite to work on the
symbolic directly without converting them.

Only reset $@ if it is necessary.

Don't call $DAISY_CHAIN via exec.

* usr/lib/pkgusr/chgrp: Don't use exec.

* usr/lib/pkgusr/chown: Ditto.

* usr/lib/pkgusr/mkdir: Ditto.

* usr/lib/pkgusr/install (_perms): Fix as per chmod.

Signed-off-by: Steve Youngs <steve@sxemacs.org>
usr/lib/pkgusr/chgrp
usr/lib/pkgusr/chmod
usr/lib/pkgusr/chown
usr/lib/pkgusr/install
usr/lib/pkgusr/mkdir

index e61e00f..16e064b 100755 (executable)
@@ -58,7 +58,7 @@ done
 if [ -z "$GRP_CHAIN" ]; then
     echo 1>&2 '***' chgrp ${cmdline}
 else
-    exec $DAISY_CHAIN ${cmdline} || exit $?
+    $DAISY_CHAIN ${cmdline} || exit $?
 fi
 
 exit 0
index 03d13ce..7810d7b 100755 (executable)
@@ -44,26 +44,25 @@ done
 # $1 should now be the perm arg
 perm=$1
 
-# Octal or symbolic?  If the latter, convert to the former.
-printf '%d' "$perm" &>/dev/null
+# Octal or symbolic?  Nuke the nasty bits (setuid etc)
+printf '%o' "0${perm}" &>/dev/null
 if [ $? -ne 0 ]; then
-    testfile=$(mktemp hack-o-matic-chmod.XXXXX --tmpdir)
-    exec $DAISY_CHAIN ${perm} ${testfile}
-    perm=$(stat --printf "%a" ${testfile})
-    rm -f ${testfile}
+    perm=${perm//[st]/}
+else
+    if [ ${perm} -gt 777 ]; then
+       perm=${perm/?/}
+    fi
 fi
 
-# if it is 4 digits, they're trying to do funky shit
-if [ ${perm} -gt 999 ]; then
-    # Chop off the 1st digit (the set{uid,gid,sticky} bit)
-    perm=${perm/?/}
+# If we changed the perm, report it and fix $@
+if [ "${perm}" != "$1" ]; then
     echo 1>&2 '***' chmod ${cmdline}
+    shift
+    set -- $perm "$@"
 fi
 
-# kill off $1 and replace it with our maybe sanitised $perm
-shift 1; set -- $perm "$@"
-
-exec $DAISY_CHAIN ${opts} "$@" || exit $?
+# Finally, run the chmod
+$DAISY_CHAIN ${opts} "$@" || exit $?
 exit 0
 
 # Local variables:
index b2e1389..4fe1671 100755 (executable)
@@ -88,7 +88,7 @@ fi
 if [ $report -eq 1 ]; then
     echo 1>&2 '***' chown ${cmdline}
 else
-    exec $DAISY_CHAIN ${cmdline} || exit $?
+    $DAISY_CHAIN ${cmdline} || exit $?
 fi
 
 exit 0
index fec2973..ab2986d 100755 (executable)
@@ -201,28 +201,23 @@ _owner()
 }
 
 ## Mode
-#  If the file perms are being set to a 4-digit number they are
-#  trying to do something funky like setuid.  In that case, truncate
-#  the 1st digit and set -m to what's left, and report it.  If perms
-#  are symbolic, convert them to numerical first.
+#  Remove any nasty bits like setuid, setgid, sticky.
 _perms()
 {
-    local testfile
-    ### HACK-O-MATIC:
-    # Convert symbolic permissions to numerical.
-    printf '%d' "$perm" &>/dev/null
+    local tperm=${perm}
+
+    printf '%o' "0${tperm}" &>/dev/null
     if [ $? -ne 0 ]; then
-       testfile=$(mktemp hack-o-matic-install.XXXXX --tmpdir)
-       # A tiny risk hard-coding /bin/chmod here, but I don't won't
-       # the chmod wrapper in play for this.
-       exec /bin/chmod ${perm} ${testfile}
-       perm=$(stat --printf "%a" ${testfile})
-       rm -f ${testfile}
+       tperm=${tperm//[st]/}
+    else
+       if [ ${tperm} -gt 777 ]; then
+           tperm=${tperm/?/}
+       fi
     fi
-    # Catch the funky shit
-    if [ $perm -gt 999 ]; then
+    # Did we change anything?
+    if [ "${tperm}" != "${perm}" ]; then
        report
-       cmdopts="$cmdopts -m${perm/?/}"
+       cmdopts="$cmdopts -m$tperm"
     else
        cmdopts="$cmdopts -m$perm"
     fi
@@ -282,7 +277,7 @@ done
 shift $(( $OPTIND - 1 ))
 
 # We've done all we can, now lets run install
-exec $DAISY_CHAIN ${cmdopts} $@ || exit $?
+$DAISY_CHAIN ${cmdopts} $@ || exit $?
 exit 0
 
 ### End install
index 75ceaa8..34dabba 100755 (executable)
@@ -45,7 +45,7 @@ for((i=$#; $i>0;))
   esac
 done
 
-exec $DAISY_CHAIN "$@" || exit $?
+$DAISY_CHAIN "$@" || exit $?
 
 test z"$dirs" != z &&
 echo 1>&2 '***' mkdir "$cmdline"