* Insecure tempfile creation @ 2014-12-22 20:36 Daniel Shahaf 2014-12-22 22:01 ` Mikael Magnusson 2014-12-28 6:30 ` Bart Schaefer 0 siblings, 2 replies; 20+ messages in thread From: Daniel Shahaf @ 2014-12-22 20:36 UTC (permalink / raw) To: zsh-workers [moving to -workers from private email] [this mail contains two mutually-exclusive (conflicting) patches] Hello. A few places in the source distribution use predictable temporary filenames; for example: Completion/Unix/Command/_cvs local d=/tmp/zsh-cvs-work-$$ Completion/compinstall: local tmpout=${TMPPREFIX:-/tmp/zsh}compinstall$$ Functions/Calendar/calendar: local mycmds="${TMPPREFIX:-/tmp/zsh}.calendar_cmds.$$" Functions/Newuser/zsh-newuser-install: local tmpfile=${TMPPREFIX:-/tmp/zsh}-zni-$$ Functions/Zftp/zfcget: local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize Functions/Zle/edit-command-line local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ Test/ztst.zsh: ZTST_in=${TMPPREFIX}.ztst.in.$$ Some of these could be vectors for symlink attacks. For example, in the edit-command-line case, a malicious local user could overwrite an arbitrary file by creating /tmp/zshecl4242 (where 4242 is the pid of an interactive zsh run by root) as a symlink and waiting for the user behind pid 4242 to run edit-command-line. (The attacker would also be able to see the contents of the edited command line, which is a problem if it contains passwords.) (Paraphrasing Bart:) In general, the "standard library" should create tempfiles in ${TMPPREFIX:-/tmp}, and take care to explicitly protect (e.g., via umask settings) any files which need to be private. So, for starters: diff --git Functions/Zle/edit-command-line Functions/Zle/edit-command-line index 250cac6..1b1762d 100644 --- Functions/Zle/edit-command-line +++ Functions/Zle/edit-command-line @@ -6,12 +6,16 @@ # will give ksh-like behaviour for that key, # except that it will handle multi-line buffers properly. -local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ - -print -R - "$PREBUFFER$BUFFER" >$tmpfile -exec </dev/tty -${=${VISUAL:-${EDITOR:-vi}}} $tmpfile -print -Rz - "$(<$tmpfile)" - -command rm -f $tmpfile -zle send-break # Force reload from the buffer stack +() { + # Use =(:) to create a temporary file with 0600 permissions, since + # the command-line may contain passwords. + local tmpfile=$1 + + print -R - "$PREBUFFER$BUFFER" >$tmpfile + exec </dev/tty + ${=${VISUAL:-${EDITOR:-vi}}} $tmpfile + print -Rz - "$(<$tmpfile)" + + command rm -f $tmpfile + zle send-break # Force reload from the buffer stack +} =(:) This causes the tempfile to be generated by gettempname(), which wraps mktemp(), eliminating the predictable filename. Do people find this use of anon functions too obfuscatory? If so, perhaps a "mktemp" builtin could be added as a thin wrapper around gettempname() (on systems that don't have a mktemp command already), and the code be converted to just: tarsus,5:src/zsh% git di diff --git Functions/Zle/edit-command-line Functions/Zle/edit-command-line index 250cac6..584ae16 100644 --- Functions/Zle/edit-command-line +++ Functions/Zle/edit-command-line @@ -6,7 +6,7 @@ # will give ksh-like behaviour for that key, # except that it will handle multi-line buffers properly. -local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ +local tmpfile=`mktemp ${TMPPREFIX:-/tmp/zsh}ecl.XXXXXX` print -R - "$PREBUFFER$BUFFER" >$tmpfile exec </dev/tty Of course, once we decide what to do with edit-command-line, it would be good to go through all the other instances and fix them too. Cheers, Daniel ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Insecure tempfile creation 2014-12-22 20:36 Insecure tempfile creation Daniel Shahaf @ 2014-12-22 22:01 ` Mikael Magnusson 2014-12-23 2:07 ` Bart Schaefer 2014-12-28 6:30 ` Bart Schaefer 1 sibling, 1 reply; 20+ messages in thread From: Mikael Magnusson @ 2014-12-22 22:01 UTC (permalink / raw) To: Daniel Shahaf; +Cc: zsh workers On Mon, Dec 22, 2014 at 9:36 PM, Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > [moving to -workers from private email] > [this mail contains two mutually-exclusive (conflicting) patches] > > Hello. > > A few places in the source distribution use predictable temporary > filenames; for example: > > Completion/Unix/Command/_cvs local d=/tmp/zsh-cvs-work-$$ > Completion/compinstall: local tmpout=${TMPPREFIX:-/tmp/zsh}compinstall$$ > Functions/Calendar/calendar: local mycmds="${TMPPREFIX:-/tmp/zsh}.calendar_cmds.$$" > Functions/Newuser/zsh-newuser-install: local tmpfile=${TMPPREFIX:-/tmp/zsh}-zni-$$ > Functions/Zftp/zfcget: local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize > Functions/Zle/edit-command-line local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ > Test/ztst.zsh: ZTST_in=${TMPPREFIX}.ztst.in.$$ > > Some of these could be vectors for symlink attacks. For example, in the > edit-command-line case, a malicious local user could overwrite an > arbitrary file by creating /tmp/zshecl4242 (where 4242 is the pid of an > interactive zsh run by root) as a symlink and waiting for the user > behind pid 4242 to run edit-command-line. (The attacker would also be > able to see the contents of the edited command line, which is a problem > if it contains passwords.) > > (Paraphrasing Bart:) In general, the "standard library" should create > tempfiles in ${TMPPREFIX:-/tmp}, and take care to explicitly protect > (e.g., via umask settings) any files which need to be private. > > So, for starters: > > diff --git Functions/Zle/edit-command-line Functions/Zle/edit-command-line > index 250cac6..1b1762d 100644 > --- Functions/Zle/edit-command-line > +++ Functions/Zle/edit-command-line > @@ -6,12 +6,16 @@ > # will give ksh-like behaviour for that key, > # except that it will handle multi-line buffers properly. > > -local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ > - > -print -R - "$PREBUFFER$BUFFER" >$tmpfile > -exec </dev/tty > -${=${VISUAL:-${EDITOR:-vi}}} $tmpfile > -print -Rz - "$(<$tmpfile)" > - > -command rm -f $tmpfile > -zle send-break # Force reload from the buffer stack > +() { > + # Use =(:) to create a temporary file with 0600 permissions, since > + # the command-line may contain passwords. > + local tmpfile=$1 > + > + print -R - "$PREBUFFER$BUFFER" >$tmpfile > + exec </dev/tty > + ${=${VISUAL:-${EDITOR:-vi}}} $tmpfile > + print -Rz - "$(<$tmpfile)" > + > + command rm -f $tmpfile > + zle send-break # Force reload from the buffer stack > +} =(:) > > This causes the tempfile to be generated by gettempname(), which wraps > mktemp(), eliminating the predictable filename. > > Do people find this use of anon functions too obfuscatory? If so, > perhaps a "mktemp" builtin could be added as a thin wrapper around > gettempname() (on systems that don't have a mktemp command already), and > the code be converted to just: Your first patch is not the best version of that solution; --- a/Functions/Zle/edit-command-line +++ b/Functions/Zle/edit-command-line @@ -6,12 +6,7 @@ # will give ksh-like behaviour for that key, # except that it will handle multi-line buffers properly. -local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ - -print -R - "$PREBUFFER$BUFFER" >$tmpfile -exec </dev/tty -${=${VISUAL:-${EDITOR:-vi}}} $tmpfile -print -Rz - "$(<$tmpfile)" - -command rm -f $tmpfile -zle send-break # Force reload from the buffer stack +() { + ${=${VISUAL:-${EDITOR:-vi}}} $1 + BUFFER="$(<$1)" +} =(print -R "$PREBUFFER$BUFFER") I don't know what the exec </dev/tty is for, but it can be added back if it's needed. I've used this patch for two years and never noticed any problems though. -- Mikael Magnusson ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Insecure tempfile creation 2014-12-22 22:01 ` Mikael Magnusson @ 2014-12-23 2:07 ` Bart Schaefer 0 siblings, 0 replies; 20+ messages in thread From: Bart Schaefer @ 2014-12-23 2:07 UTC (permalink / raw) To: zsh workers On Dec 22, 11:01pm, Mikael Magnusson wrote: } } Your first patch is not the best version of that solution; } } +() { } + ${=${VISUAL:-${EDITOR:-vi}}} $1 } + BUFFER="$(<$1)" } +} =(print -R "$PREBUFFER$BUFFER") Even that isn't the best formulation, =(<<<"$PREBUFFER$BUFFER") would avoid forking the print. } I don't know what the exec </dev/tty is for, but it can be added back } if it's needed. I've used this patch for two years and never noticed } any problems though. Widgets run with stdin closed, so if the chosen editor doesn't open the tty or one of the other std*s directly, it breaks without </dev/tty. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Insecure tempfile creation 2014-12-22 20:36 Insecure tempfile creation Daniel Shahaf 2014-12-22 22:01 ` Mikael Magnusson @ 2014-12-28 6:30 ` Bart Schaefer 2014-12-28 7:44 ` [PATCH] " Bart Schaefer 1 sibling, 1 reply; 20+ messages in thread From: Bart Schaefer @ 2014-12-28 6:30 UTC (permalink / raw) To: zsh-workers On Dec 22, 8:36pm, Daniel Shahaf wrote: } } Of course, once we decide what to do with edit-command-line, it would be } good to go through all the other instances and fix them too. Question related to this: Is there some reason the following does NOT work? Does zftp fail in the subshell? diff --git a/Functions/Zftp/zffcache b/Functions/Zftp/zffcache index 48afdcb..b609c21 100644 --- a/Functions/Zftp/zffcache +++ b/Functions/Zftp/zffcache @@ -19,8 +19,5 @@ fi if [[ $1 = -d ]]; then unset $fcache_name elif (( ${(P)#fcache_name} == 0 )); then - local tmpf=${TMPPREFIX}zffcache$$ - zftp ls >$tmpf - eval "$fcache_name=(\${(f)\"\$(<\$tmpf)\"})" - rm -f $tmpf + eval "$fcache_name=(\${(f)\"\$(zftp ls)\"})" fi ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH] Re: Insecure tempfile creation 2014-12-28 6:30 ` Bart Schaefer @ 2014-12-28 7:44 ` Bart Schaefer 2014-12-28 8:41 ` Bart Schaefer 0 siblings, 1 reply; 20+ messages in thread From: Bart Schaefer @ 2014-12-28 7:44 UTC (permalink / raw) To: zsh-workers On Dec 27, 10:30pm, Bart Schaefer wrote: } } } Of course, once we decide what to do with edit-command-line, it would be } } good to go through all the other instances and fix them too. } } Question related to this: Is there some reason the following does NOT } work? Does zftp fail in the subshell? I found at least one other place where $(zftp ...) was being used, so I presume this is OK. However, somebody (mystical chanting) should check my work in Functions/Zftp/. In the patch below, cases where the use of the temporary file was easily localized or the name didn't matter, I used anonymous functions with an argument created by =(:). Where the name seemed to matter or the usage was scattered, I applied a trick that occurred to me when looking at Functions/Calendar/calendar, to wit: mv -f =(:) tmpfilename The file is created safely and with mode 0600 by =(:) and then renamed to the desired name, which will replace any symlink or other file that has been left in in the way. I then made sure that redirects either used ">>" (knowing the file is empty) or ">|" to avoid issues with noclobber. I think a few files in Zftp may need "emulate zsh" but I did not attempt to fix that. I suppose =(<<<'') would actually be better, since it won't fork. Hm. In compinstall I noticed that a second tempfile was created by adding the digit "2" to a file name already ending in a PID. Since this could collide with the PID of a different shell, I changed it to append "x". This patch does not yet tackle uses of "/tmp" that do not use $TMPPREFIX, nor did I attempt to retrofit zsh-newuser-install, which uses a common prefix name built on $TMPPREFIX for several different files. diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug index 6044863..00f600e 100644 --- a/Completion/Base/Widget/_complete_debug +++ b/Completion/Base/Widget/_complete_debug @@ -9,6 +9,7 @@ local pager w="${(qq)words}" integer debug_fd=-1 { if [[ -t 2 ]]; then + mv -f =(:) $tmp && exec {debug_fd}>&2 2>| $tmp fi diff --git a/Completion/compinstall b/Completion/compinstall index c04543c..7d34ee4 100644 --- a/Completion/compinstall +++ b/Completion/compinstall @@ -1958,11 +1958,14 @@ if [[ -z $ifile || -d $ifile ]] || fi local tmpout=${TMPPREFIX:-/tmp/zsh}compinstall$$ +mv -f =(:) $tmpout && # safe tempfile creation +mv -f =(:) ${tmpout}x || return 1 + # # Assemble the complete set of lines to # insert. # -__ci_output >$tmpout +__ci_output >>$tmpout if [[ -n $ifile ]]; then if [[ $ifile != *(zshrc|zlogin|zshenv) ]]; then @@ -1984,15 +1987,15 @@ future use." fi if { { grep "$endline" $ifile >/dev/null 2>&1 && sed -e "/^[ ]*$endline/r $tmpout -/^[ ]*$startline/,/^[ ]*$endline/d" $ifile >${tmpout}2 } || - { cp $ifile ${tmpout}2 && cat $tmpout >>${tmpout}2 } } && - cp ${tmpout}2 $ifile && rm -f ${tmpout}2; then +/^[ ]*$startline/,/^[ ]*$endline/d" $ifile >>${tmpout}x } || + { cp $ifile ${tmpout}x && cat $tmpout >>${tmpout}x } } && + cp ${tmpout}x $ifile && rm -f ${tmpout}x; then print "\nSuccessfully added compinstall lines to $ifile." rm -f $tmpout else print "\nFailure adding lines to $ifile. Lines left in \`$tmpout'" fi - rm -f ${tmpout}2 + rm -f ${tmpout}x elif read -q key'?Print them to stdout instead ([y]es, [n]o)? '; then cat $tmpout rm -f $tmpout diff --git a/Functions/Calendar/calendar b/Functions/Calendar/calendar index 00f5998..08c4250 100644 --- a/Functions/Calendar/calendar +++ b/Functions/Calendar/calendar @@ -254,8 +254,7 @@ if (( verbose )); then fi local mycmds="${TMPPREFIX:-/tmp/zsh}.calendar_cmds.$$" -touch $mycmds -chmod 600 $mycmds +mv -f =(:) $mycmds # start of subshell for OS file locking ( diff --git a/Functions/Zftp/zfcd_match b/Functions/Zftp/zfcd_match index 95de4c5..2c809c2 100644 --- a/Functions/Zftp/zfcd_match +++ b/Functions/Zftp/zfcd_match @@ -12,7 +12,6 @@ fi local ZFTP_VERBOSE=45 # should we redirect 2>/dev/null or let the user see it? -local tmpf=${TMPPREFIX}zfcm$$ local -a match mbegin mend if [[ $ZFTP_SYSTEM = UNIX* ]]; then @@ -27,9 +26,10 @@ if [[ $ZFTP_SYSTEM = UNIX* ]]; then # If we're using -F, we get away with using a directory # to list, but not a glob. Don't ask me why. reply=(${${(M)${(f)"$(zftp ls -lF $dir)"}:#d*}/(#b)*[[:space:]](*)\//$match[1]}) -# zftp ls -LF $dir >$tmpf -# reply=($(awk '/\/$/ { print substr($1, 1, length($1)-1) }' $tmpf)) -# rm -f $tmpf +# () { +# zftp ls -LF $dir >|$1 +# reply=($(awk '/\/$/ { print substr($1, 1, length($1)-1) }' $1)) +# } =(:) [[ -n $dir && $dir != */ ]] && dir="$dir/" if [[ -n $WIDGET ]]; then _wanted directories expl 'remote directory' \ diff --git a/Functions/Zftp/zfcget b/Functions/Zftp/zfcget index 476a730..4359801 100644 --- a/Functions/Zftp/zfcget +++ b/Functions/Zftp/zfcget @@ -14,7 +14,7 @@ emulate -L zsh [[ $curcontext = :zf* ]] || local curcontext=:zfcget local loc rem stat=0 opt opt_G opt_t remlist locst remst -local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize +local rstat tsize while getopts :Gt opt; do [[ $opt = '?' ]] && print "zfcget: bad option: -$OPTARG" && return 1 @@ -39,10 +39,11 @@ for remlist in $*; do else # Compare the sizes. locst=($(zftp local $loc)) - zftp remote $rem >$tmpfile - rstat=$? - remst=($(<$tmpfile)) - rm -f $tmpfile + () { + zftp remote $rem >|$1 + rstat=$? + remst=($(<$1)) + } =(: temporary file) if [[ $rstat = 2 ]]; then print "Server does not support SIZE command.\n" \ "Assuming you know what you're doing..." 2>&1 diff --git a/Functions/Zftp/zfcput b/Functions/Zftp/zfcput index 85141b6..2cf8fe2 100644 --- a/Functions/Zftp/zfcput +++ b/Functions/Zftp/zfcput @@ -14,7 +14,6 @@ emulate -L zsh [[ $curcontext = :zf* ]] || local curcontext=:zfcput local loc rem stat=0 locst remst offs tailtype -local tmpfile=${TMPPREFIX}zfcget$$ rstat # find how tail works. this is intensely annoying, since it's completely # standard in C. od's no use, since we can only skip whole blocks. @@ -40,10 +39,11 @@ for loc in $*; do else # Compare the sizes. locst=($(zftp local $loc)) - zftp remote $rem >$tmpfile - rstat=$? - remst=($(<$tmpfile)) - rm -f $tmpfile + () { + zftp remote $rem >|$1 + rstat=$? + remst=($(<$1)) + } =(: temporary file) if [[ $rstat = 2 ]]; then print "Server does not support remote status commands.\n" \ "You will have to find out the size by hand and use zftp append." 2>&1 diff --git a/Functions/Zftp/zffcache b/Functions/Zftp/zffcache index 48afdcb..b609c21 100644 --- a/Functions/Zftp/zffcache +++ b/Functions/Zftp/zffcache @@ -19,8 +19,5 @@ fi if [[ $1 = -d ]]; then unset $fcache_name elif (( ${(P)#fcache_name} == 0 )); then - local tmpf=${TMPPREFIX}zffcache$$ - zftp ls >$tmpf - eval "$fcache_name=(\${(f)\"\$(<\$tmpf)\"})" - rm -f $tmpf + eval "$fcache_name=(\${(f)\"\$(zftp ls)\"})" fi diff --git a/Functions/Zftp/zfget_match b/Functions/Zftp/zfget_match index 1d90bea..c2871fa 100644 --- a/Functions/Zftp/zfget_match +++ b/Functions/Zftp/zfget_match @@ -7,22 +7,22 @@ if [[ $1 == $HOME || $1 == $HOME/* ]]; then 1="~${1#$HOME}" fi -local tmpf=${TMPPREFIX}zfgm$$ - if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then + setopt localoptions clobber + local tmpf=${TMPPREFIX}zfgm$$ + mv -f =(:) $tmpf + if [[ -n $WIDGET ]]; then local dir=${1:h} [[ $dir = */ ]] || dir="$dir/" zftp ls -LF $dir >$tmpf local reply reply=(${${${(f)"$(<$tmpf)"}##$dir}%\*}) - rm -f $tmpf _wanted files expl 'remote file' compadd -P $dir - $reply else # On the first argument to ls, we usually get away with a glob. zftp ls "$1*$2" >$tmpf reply=($(<$tmpf)) - rm -f $tmpf fi else local fcache_name diff --git a/Functions/Zftp/zfrglob b/Functions/Zftp/zfrglob index 1fb8d76..5015be7 100644 --- a/Functions/Zftp/zfrglob +++ b/Functions/Zftp/zfrglob @@ -33,12 +33,12 @@ if [[ $pat != *[][*?]* && ( -n $zfrglob || $pat != *[(|)#^]* ) ]]; then return 0 fi -local tmpf=${TMPPREFIX}zfrglob$$ if [[ $zfrglob != '' ]]; then - zftp ls "$pat" >$tmpf 2>/dev/null - eval "$1=(\$(<\$tmpf))" - rm -f $tmpf + () { + zftp ls "$pat" >|$1 2>/dev/null + eval "$1=(\$(<\$1))" + } =(: temporary file) else if [[ $ZFTP_SYSTEM = UNIX* && $pat = */* ]]; then # not the current directory and we know how to handle paths @@ -49,10 +49,11 @@ else dir=/ fi nondir=${pat##*/} - zftp ls "$dir" 2>/dev/null >$tmpf - files=($(<$tmpf)) + () { + zftp ls "$dir" 2>/dev/null >|$1 + files=($(<$1)) + } =(: temporary file) files=(${files:t}) - rm -f $tmpf else # we just have to do an ls and hope that's right local fcache_name diff --git a/Functions/Zftp/zftransfer b/Functions/Zftp/zftransfer index c70bf72..432e2f5 100644 --- a/Functions/Zftp/zftransfer +++ b/Functions/Zftp/zftransfer @@ -43,10 +43,11 @@ zfautocheck || return 1 local style zstyle -s ':zftp:zftransfer' progress style if [[ -n $style && $style != none ]]; then - local ZFTP_TSIZE array tmpfile=${TMPPREFIX}zft$$ - zftp remote $file1 >$tmpfile 2>/dev/null - array=($(<$tmpfile)) - rm -f $tmpfile + local ZFTP_TSIZE array + () { + zftp remote $file1 >|$1 2>/dev/null + array=($(<$1)) + } =(: temporary file) [[ $#array -eq 2 ]] && ZFTP_TSIZE=$array[1] fi diff --git a/Functions/Zftp/zftype b/Functions/Zftp/zftype index 0cdf7e2..81f95de 100644 --- a/Functions/Zftp/zftype +++ b/Functions/Zftp/zftype @@ -1,13 +1,11 @@ # function zftype { -local type zftmp=${TMPPREFIX}zftype$$ +local type [[ $curcontext = :zf* ]] || local curcontext=:zftype zfautocheck -d if (( $# == 0 )); then - zftp type >$zftmp - type=$(<$zftmp) - rm -f $zftmp + type=$(zftp type) if [[ $type = I ]]; then print "Current type is image (binary)" return 0 diff --git a/Functions/Zftp/zfuget b/Functions/Zftp/zfuget index c1033c9..7bdaedc 100644 --- a/Functions/Zftp/zfuget +++ b/Functions/Zftp/zfuget @@ -26,7 +26,7 @@ emulate -L zsh [[ $curcontext = :zf* ]] || local curcontext=:zfuget -local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$ +local loc rem locstats remstats doit local rstat remlist opt opt_v opt_s opt_G opt_t integer stat do_close @@ -66,12 +66,13 @@ for remlist in $*; do doit=y remstats=() if [[ -f $loc ]]; then - zftp local $loc >$tmpfile - locstats=($(<$tmpfile)) - zftp remote $rem >$tmpfile - rstat=$? - remstats=($(<$tmpfile)) - rm -f $tmpfile + () { + zftp local $loc >|$1 + locstats=($(<$1)) + zftp remote $rem >|$1 + rstat=$? + remstats=($(<$1)) + } =(: temporary file) if [[ $rstat = 2 ]]; then print "Server does not implement full command set required." 1>&2 return 1 diff --git a/Functions/Zftp/zfuput b/Functions/Zftp/zfuput index 4e0e42d..24a3559 100644 --- a/Functions/Zftp/zfuput +++ b/Functions/Zftp/zfuput @@ -12,7 +12,7 @@ emulate -L zsh [[ $curcontext = :zf* ]] || local curcontext=:zfuput -local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuput$$ +local loc rem locstats remstats doit local rstat opt opt_v opt_s integer stat do_close @@ -52,12 +52,13 @@ for rem in $*; do stat=1 continue fi - zftp local $loc >$tmpfile - locstats=($(<$tmpfile)) - zftp remote $rem >$tmpfile - rstat=$? - remstats=($(<$tmpfile)) - rm -f $tmpfile + () { + zftp local $loc >|$1 + locstats=($(<$1)) + zftp remote $rem >|$1 + rstat=$? + remstats=($(<$1)) + } =(: temporary file) if [[ $rstat = 2 ]]; then print "Server does not implement full command set required." 1>&2 return 1 diff --git a/Functions/Zle/edit-command-line b/Functions/Zle/edit-command-line index 250cac6..100af96 100644 --- a/Functions/Zle/edit-command-line +++ b/Functions/Zle/edit-command-line @@ -6,12 +6,10 @@ # will give ksh-like behaviour for that key, # except that it will handle multi-line buffers properly. -local tmpfile=${TMPPREFIX:-/tmp/zsh}ecl$$ +() { + exec </dev/tty + ${=${VISUAL:-${EDITOR:-vi}}} $1 + print -Rz - "$(<$1)" +} =(<<<"$PREBUFFER$BUFFER") -print -R - "$PREBUFFER$BUFFER" >$tmpfile -exec </dev/tty -${=${VISUAL:-${EDITOR:-vi}}} $tmpfile -print -Rz - "$(<$tmpfile)" - -command rm -f $tmpfile zle send-break # Force reload from the buffer stack -- Barton E. Schaefer ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2014-12-28 7:44 ` [PATCH] " Bart Schaefer @ 2014-12-28 8:41 ` Bart Schaefer 2014-12-29 0:49 ` Daniel Shahaf 0 siblings, 1 reply; 20+ messages in thread From: Bart Schaefer @ 2014-12-28 8:41 UTC (permalink / raw) To: zsh-workers On Dec 27, 11:44pm, Bart Schaefer wrote: } } I suppose =(<<<'') would actually be better, since it won't fork. Hm. } } This patch does not yet tackle uses of "/tmp" that do not use $TMPPREFIX Fortunately I didn't find any of the latter except for the previously identified one in _cvs (_cvs_run). So the patch below changes the use of =(:) to =(<<<'') and repairs _cvs_run to create the temp directory in a safe (I hope) manner. Apply on top of 34067. diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug index 00f600e..50fc809 100644 --- a/Completion/Base/Widget/_complete_debug +++ b/Completion/Base/Widget/_complete_debug @@ -9,7 +9,7 @@ local pager w="${(qq)words}" integer debug_fd=-1 { if [[ -t 2 ]]; then - mv -f =(:) $tmp && + mv -f =(<<<'') $tmp && exec {debug_fd}>&2 2>| $tmp fi diff --git a/Completion/Unix/Command/_cvs b/Completion/Unix/Command/_cvs index 3c06e04..31997ec 100644 --- a/Completion/Unix/Command/_cvs +++ b/Completion/Unix/Command/_cvs @@ -704,15 +704,18 @@ _cvs_sub_modules() { _cvs_run() { local cvsroot="$1" dir="$2" shift 2 - local d=/tmp/zsh-cvs-work-$$ - mkdir $d >&/dev/null - cd $d - mkdir CVS >&/dev/null + local d=${TMPPREFIX:-/tmp/zsh}-cvs-work-$$ + rm -rf $d + mkdir $d && + ( + chmod 0700 $d && + builtin cd -q $d && + mkdir CVS >&/dev/null || return 1 print -r - "$cvsroot" > CVS/Root print "$dir" > CVS/Repository print D > CVS/Entries CVS_IGNORE_REMOTE_ROOT= cvs "$@" - cd $OLDPWD + ) rm -rf $d } diff --git a/Completion/compinstall b/Completion/compinstall index 7d34ee4..ae94993 100644 --- a/Completion/compinstall +++ b/Completion/compinstall @@ -1958,8 +1958,8 @@ if [[ -z $ifile || -d $ifile ]] || fi local tmpout=${TMPPREFIX:-/tmp/zsh}compinstall$$ -mv -f =(:) $tmpout && # safe tempfile creation -mv -f =(:) ${tmpout}x || return 1 +mv -f =(<<<'') $tmpout && # safe tempfile creation +mv -f =(<<<'') ${tmpout}x || return 1 # # Assemble the complete set of lines to diff --git a/Functions/Calendar/calendar b/Functions/Calendar/calendar index 08c4250..39fc431 100644 --- a/Functions/Calendar/calendar +++ b/Functions/Calendar/calendar @@ -254,7 +254,7 @@ if (( verbose )); then fi local mycmds="${TMPPREFIX:-/tmp/zsh}.calendar_cmds.$$" -mv -f =(:) $mycmds +mv -f =(<<<'') $mycmds # start of subshell for OS file locking ( diff --git a/Functions/Zftp/zfcd_match b/Functions/Zftp/zfcd_match index 2c809c2..9159f49 100644 --- a/Functions/Zftp/zfcd_match +++ b/Functions/Zftp/zfcd_match @@ -29,7 +29,7 @@ if [[ $ZFTP_SYSTEM = UNIX* ]]; then # () { # zftp ls -LF $dir >|$1 # reply=($(awk '/\/$/ { print substr($1, 1, length($1)-1) }' $1)) -# } =(:) +# } =(<<<'') [[ -n $dir && $dir != */ ]] && dir="$dir/" if [[ -n $WIDGET ]]; then _wanted directories expl 'remote directory' \ diff --git a/Functions/Zftp/zfcget b/Functions/Zftp/zfcget index 4359801..569ee9d 100644 --- a/Functions/Zftp/zfcget +++ b/Functions/Zftp/zfcget @@ -43,7 +43,7 @@ for remlist in $*; do zftp remote $rem >|$1 rstat=$? remst=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') if [[ $rstat = 2 ]]; then print "Server does not support SIZE command.\n" \ "Assuming you know what you're doing..." 2>&1 diff --git a/Functions/Zftp/zfcput b/Functions/Zftp/zfcput index 2cf8fe2..eafecde 100644 --- a/Functions/Zftp/zfcput +++ b/Functions/Zftp/zfcput @@ -43,7 +43,7 @@ for loc in $*; do zftp remote $rem >|$1 rstat=$? remst=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') if [[ $rstat = 2 ]]; then print "Server does not support remote status commands.\n" \ "You will have to find out the size by hand and use zftp append." 2>&1 diff --git a/Functions/Zftp/zfget_match b/Functions/Zftp/zfget_match index c2871fa..3ba06c4 100644 --- a/Functions/Zftp/zfget_match +++ b/Functions/Zftp/zfget_match @@ -10,7 +10,7 @@ fi if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then setopt localoptions clobber local tmpf=${TMPPREFIX}zfgm$$ - mv -f =(:) $tmpf + mv -f =(<<<'') $tmpf if [[ -n $WIDGET ]]; then local dir=${1:h} diff --git a/Functions/Zftp/zfrglob b/Functions/Zftp/zfrglob index 5015be7..677b85f 100644 --- a/Functions/Zftp/zfrglob +++ b/Functions/Zftp/zfrglob @@ -38,7 +38,7 @@ if [[ $zfrglob != '' ]]; then () { zftp ls "$pat" >|$1 2>/dev/null eval "$1=(\$(<\$1))" - } =(: temporary file) + } =(<<<'temporary file') else if [[ $ZFTP_SYSTEM = UNIX* && $pat = */* ]]; then # not the current directory and we know how to handle paths @@ -52,7 +52,7 @@ else () { zftp ls "$dir" 2>/dev/null >|$1 files=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') files=(${files:t}) else # we just have to do an ls and hope that's right diff --git a/Functions/Zftp/zftransfer b/Functions/Zftp/zftransfer index 432e2f5..c97ae46 100644 --- a/Functions/Zftp/zftransfer +++ b/Functions/Zftp/zftransfer @@ -47,7 +47,7 @@ if [[ -n $style && $style != none ]]; then () { zftp remote $file1 >|$1 2>/dev/null array=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') [[ $#array -eq 2 ]] && ZFTP_TSIZE=$array[1] fi diff --git a/Functions/Zftp/zfuget b/Functions/Zftp/zfuget index 7bdaedc..2850975 100644 --- a/Functions/Zftp/zfuget +++ b/Functions/Zftp/zfuget @@ -72,7 +72,7 @@ for remlist in $*; do zftp remote $rem >|$1 rstat=$? remstats=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') if [[ $rstat = 2 ]]; then print "Server does not implement full command set required." 1>&2 return 1 diff --git a/Functions/Zftp/zfuput b/Functions/Zftp/zfuput index 24a3559..f4e6a0f 100644 --- a/Functions/Zftp/zfuput +++ b/Functions/Zftp/zfuput @@ -58,7 +58,7 @@ for rem in $*; do zftp remote $rem >|$1 rstat=$? remstats=($(<$1)) - } =(: temporary file) + } =(<<<'temporary file') if [[ $rstat = 2 ]]; then print "Server does not implement full command set required." 1>&2 return 1 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2014-12-28 8:41 ` Bart Schaefer @ 2014-12-29 0:49 ` Daniel Shahaf 2014-12-29 4:01 ` Bart Schaefer 0 siblings, 1 reply; 20+ messages in thread From: Daniel Shahaf @ 2014-12-29 0:49 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers Bart Schaefer wrote on Sun, Dec 28, 2014 at 00:41:01 -0800: > On Dec 27, 11:44pm, Bart Schaefer wrote: > } > } I suppose =(<<<'') would actually be better, since it won't fork. Hm. > } > } This patch does not yet tackle uses of "/tmp" that do not use $TMPPREFIX > > Fortunately I didn't find any of the latter except for the previously > identified one in _cvs (_cvs_run). So the patch below changes the use > of =(:) to =(<<<'') and repairs _cvs_run to create the temp directory > in a safe (I hope) manner. Apply on top of 34067. > First of all, thanks for picking this up. I'd meant to get back to this thread early January, but I'm happy to have been beaten to it :-) Your patches look good to me, including the rmdir, but except for: > - } =(: temporary file) > + } =(<<<'temporary file') I assume =(<<<'') was the intention. Thanks again, Daniel ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2014-12-29 0:49 ` Daniel Shahaf @ 2014-12-29 4:01 ` Bart Schaefer 2015-01-07 22:03 ` Daniel Shahaf 0 siblings, 1 reply; 20+ messages in thread From: Bart Schaefer @ 2014-12-29 4:01 UTC (permalink / raw) To: zsh-workers On Dec 29, 12:49am, Daniel Shahaf wrote: } } Your patches look good to me, including the rmdir I avoided using "mkdir -m 0700" in favor of the chmod but then found some other places where mkdir is passed the -m option. So maybe that should be tweaked. } but except for: } } > - } =(: temporary file) } > + } =(<<<'temporary file') } } I assume =(<<<'') was the intention. I meant to say something about that but forgot. The places where I left that immediately use >|$1 to clobber the file, so it doesn't matter if the file starts out empty; I hoped it could be a clue to the reader what was going on. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2014-12-29 4:01 ` Bart Schaefer @ 2015-01-07 22:03 ` Daniel Shahaf 2015-01-08 6:22 ` Bart Schaefer 0 siblings, 1 reply; 20+ messages in thread From: Daniel Shahaf @ 2015-01-07 22:03 UTC (permalink / raw) To: zsh-workers Bart Schaefer wrote on Sun, Dec 28, 2014 at 20:01:42 -0800: > On Dec 29, 12:49am, Daniel Shahaf wrote: > } > } Your patches look good to me, including the rmdir > > I avoided using "mkdir -m 0700" in favor of the chmod but then found some > other places where mkdir is passed the -m option. So maybe that should > be tweaked. Coming back to this, it has occurred to me that mv -f =(:) ${TMPPREFIX:-/tmp/zsh}foo$$ wouldn't perform an atomic rename (as intended) if /tmp/zshfoo$$ is a directory or symlink-to-directory. So hypothetically an attacker might be able to create a file named `basename =(:)` in a directory of his choice owned by the victim. I realize this is more far-fetched than the previous scenario. Do we consider this a problem that should be fixed? Cheers, Daniel ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-07 22:03 ` Daniel Shahaf @ 2015-01-08 6:22 ` Bart Schaefer 2015-01-08 6:48 ` Danek Duvall 0 siblings, 1 reply; 20+ messages in thread From: Bart Schaefer @ 2015-01-08 6:22 UTC (permalink / raw) To: Zsh hackers list On Wed, Jan 7, 2015 at 2:03 PM, Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > Coming back to this, it has occurred to me that > > mv -f =(:) ${TMPPREFIX:-/tmp/zsh}foo$$ > > wouldn't perform an atomic rename (as intended) if /tmp/zshfoo$$ is a > directory or symlink-to-directory. So hypothetically an attacker might > be able to create a file named `basename =(:)` in a directory of his > choice owned by the victim. Hmm. Yup, we need "ln -Fh" instead of "mv -f". Are the -F and -h options of "ln" fairly standard? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 6:22 ` Bart Schaefer @ 2015-01-08 6:48 ` Danek Duvall 2015-01-08 8:08 ` Bart Schaefer 0 siblings, 1 reply; 20+ messages in thread From: Danek Duvall @ 2015-01-08 6:48 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh hackers list On Wed, Jan 07, 2015 at 10:22:20PM -0800, Bart Schaefer wrote: > On Wed, Jan 7, 2015 at 2:03 PM, Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > > Coming back to this, it has occurred to me that > > > > mv -f =(:) ${TMPPREFIX:-/tmp/zsh}foo$$ > > > > wouldn't perform an atomic rename (as intended) if /tmp/zshfoo$$ is a > > directory or symlink-to-directory. So hypothetically an attacker might > > be able to create a file named `basename =(:)` in a directory of his > > choice owned by the victim. > > Hmm. Yup, we need "ln -Fh" instead of "mv -f". Are the -F and -h > options of "ln" fairly standard? Neither exists on Solaris ln. GNU coreutils ln doesn't seem to have -h, either. And -F just seems like a bad idea, supported or not. What about mktemp? The above construction is pretty weird, anyway. If an external command isn't desired, then mktemp seems like a reasonable thing to make builtin. Danek ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 6:48 ` Danek Duvall @ 2015-01-08 8:08 ` Bart Schaefer 2015-01-08 14:10 ` Daniel Shahaf 2015-01-08 14:24 ` Peter Stephenson 0 siblings, 2 replies; 20+ messages in thread From: Bart Schaefer @ 2015-01-08 8:08 UTC (permalink / raw) To: Zsh hackers list On Jan 7, 10:48pm, Danek Duvall wrote: } Subject: Re: [PATCH] Re: Insecure tempfile creation } } On Wed, Jan 07, 2015 at 10:22:20PM -0800, Bart Schaefer wrote: } } > On Wed, Jan 7, 2015 at 2:03 PM, Daniel Shahaf <d.s@daniel.shahaf.name> wrote: } > > Coming back to this, it has occurred to me that } > > } > > mv -f =(:) ${TMPPREFIX:-/tmp/zsh}foo$$ } > > } > } > Hmm. Yup, we need "ln -Fh" instead of "mv -f". Are the -F and -h } > options of "ln" fairly standard? } } Neither exists on Solaris ln. GNU coreutils ln doesn't seem to have -h, } either. And -F just seems like a bad idea, supported or not. -F on MacOS (where I was reading the manual) is like -f in coreutils, not like -F in coreutils (sigh). And -h is --no-dereference. } What about mktemp? That doesn't help; it's exactly the same as =(:) for this purpose. The "mv" trick above is used where we need to create a file with a specific name -- if we did not need a specific name, we could just use the name created by =(:) directly. Fortunately, we have the zsh/files module which provides a buitin "ln" with well-defined semantics. Hopefully that's good enough. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 8:08 ` Bart Schaefer @ 2015-01-08 14:10 ` Daniel Shahaf 2015-01-08 14:24 ` Peter Stephenson 1 sibling, 0 replies; 20+ messages in thread From: Daniel Shahaf @ 2015-01-08 14:10 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh hackers list Bart Schaefer wrote on Thu, Jan 08, 2015 at 00:08:21 -0800: > On Jan 7, 10:48pm, Danek Duvall wrote: > } Subject: Re: [PATCH] Re: Insecure tempfile creation > } > } On Wed, Jan 07, 2015 at 10:22:20PM -0800, Bart Schaefer wrote: > } > } > On Wed, Jan 7, 2015 at 2:03 PM, Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > } > > Coming back to this, it has occurred to me that > } > > > } > > mv -f =(:) ${TMPPREFIX:-/tmp/zsh}foo$$ > } > > > } > > } > Hmm. Yup, we need "ln -Fh" instead of "mv -f". Are the -F and -h > } > options of "ln" fairly standard? > } > } Neither exists on Solaris ln. GNU coreutils ln doesn't seem to have -h, > } either. And -F just seems like a bad idea, supported or not. > > -F on MacOS (where I was reading the manual) is like -f in coreutils, > not like -F in coreutils (sigh). And -h is --no-dereference. > So, for clarity, the flags you proposed mean "overwrite destination if existing" and "if destination is symlink, don't dereference it". > Fortunately, we have the zsh/files module which provides a buitin "ln" > with well-defined semantics. Hopefully that's good enough. Another option: add a builtin that wraps the rename(2) syscall, and then use: zrename =(<<<'') ${TMPPREFIX:-/tmp/zsh}foo$$ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 8:08 ` Bart Schaefer 2015-01-08 14:10 ` Daniel Shahaf @ 2015-01-08 14:24 ` Peter Stephenson 2015-01-08 16:35 ` Ray Andrews 2015-01-09 2:51 ` Mikael Magnusson 1 sibling, 2 replies; 20+ messages in thread From: Peter Stephenson @ 2015-01-08 14:24 UTC (permalink / raw) To: Zsh hackers list On Thu, 8 Jan 2015 00:08:21 -0800 Bart Schaefer <schaefer@brasslantern.com> wrote: > Fortunately, we have the zsh/files module which provides a buitin "ln" > with well-defined semantics. Hopefully that's good enough. It's a little bit tangential, but it's always bothered me that the only option we have for module builtins of this kind is to import the into the command namespace under the standard name, trashing the use of the system-standard utility your code may elsewhere depend on That is, you can use "command ln" if you need to, but the point is in the majority of existing code you would never have bothered to do that. We made special arrangements for (z)stat but that really doesn't scale well. Apart from (z)stat, most of the builtins that look like standard utilies are only there for special cases, e.g. for some reason you can't get to the file system where they live, in which case there's no real problem. But for uses like this there potentially is. pws ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 14:24 ` Peter Stephenson @ 2015-01-08 16:35 ` Ray Andrews 2015-01-08 17:40 ` Peter Stephenson 2015-01-09 2:51 ` Mikael Magnusson 1 sibling, 1 reply; 20+ messages in thread From: Ray Andrews @ 2015-01-08 16:35 UTC (permalink / raw) To: zsh-workers On 01/08/2015 06:24 AM, Peter Stephenson wrote: > On Thu, 8 Jan 2015 00:08:21 -0800 > Bart Schaefer <schaefer@brasslantern.com> wrote: >> Fortunately, we have the zsh/files module which provides a buitin "ln" >> with well-defined semantics. Hopefully that's good enough. > It's a little bit tangential, but it's always bothered me that the only > option we have for module builtins of this kind is to import the into > the command namespace under the standard name, trashing the use of the > system-standard utility your code may elsewhere depend on That is, you > can use "command ln" if you need to, but the point is in the majority of > existing code you would never have bothered to do that. > > We made special arrangements for (z)stat but that really doesn't scale > well. > > Apart from (z)stat, most of the builtins that look like standard utilies > are only there for special cases, e.g. for some reason you can't get to > the file system where they live, in which case there's no real problem. > But for uses like this there potentially is. What an interesting thought. Reading, as I just did about some 'other' 'ln' I: '$ whence ln' and what I get is '/bin/ln' ... and I shrug my shoulders and move on. So are you saying that zsh has an internal 'ln'? If so how can I learn about it? I know we have uniquely named zsh functions, but I have no idea about any that share standard names. man zshbuiltins doesn't mention any 'ln'. What am I missing? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 16:35 ` Ray Andrews @ 2015-01-08 17:40 ` Peter Stephenson 0 siblings, 0 replies; 20+ messages in thread From: Peter Stephenson @ 2015-01-08 17:40 UTC (permalink / raw) To: zsh-workers On Thu, 8 Jan 2015 08:35:47 -0800 Ray Andrews <rayandrews@eastlink.ca> wrote: > 'ln' I: '$ whence ln' and what I get is '/bin/ln' ... and I shrug my > shoulders and move on. > So are you saying that zsh has an internal 'ln'? If so how can I learn > about it? It's in the zsh/files module. See "man zshmodules". This is more of a zsh-users question. pws ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-08 14:24 ` Peter Stephenson 2015-01-08 16:35 ` Ray Andrews @ 2015-01-09 2:51 ` Mikael Magnusson 2015-01-09 9:02 ` Peter Stephenson 1 sibling, 1 reply; 20+ messages in thread From: Mikael Magnusson @ 2015-01-09 2:51 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh hackers list On Thu, Jan 8, 2015 at 3:24 PM, Peter Stephenson <p.stephenson@samsung.com> wrote: > On Thu, 8 Jan 2015 00:08:21 -0800 > Bart Schaefer <schaefer@brasslantern.com> wrote: >> Fortunately, we have the zsh/files module which provides a buitin "ln" >> with well-defined semantics. Hopefully that's good enough. > > It's a little bit tangential, but it's always bothered me that the only > option we have for module builtins of this kind is to import the into > the command namespace under the standard name, trashing the use of the > system-standard utility your code may elsewhere depend on That is, you > can use "command ln" if you need to, but the point is in the majority of > existing code you would never have bothered to do that. > > We made special arrangements for (z)stat but that really doesn't scale > well. > > Apart from (z)stat, most of the builtins that look like standard utilies > are only there for special cases, e.g. for some reason you can't get to > the file system where they live, in which case there's no real problem. > But for uses like this there potentially is. Actually all the builtins foo in zsh/files are also available as zf_foo. -- Mikael Magnusson ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-09 2:51 ` Mikael Magnusson @ 2015-01-09 9:02 ` Peter Stephenson 2015-01-09 12:51 ` Peter Stephenson 0 siblings, 1 reply; 20+ messages in thread From: Peter Stephenson @ 2015-01-09 9:02 UTC (permalink / raw) To: Zsh hackers list On Fri, 9 Jan 2015 03:51:01 +0100 Mikael Magnusson <mikachu@gmail.com> wrote: > On Thu, Jan 8, 2015 at 3:24 PM, Peter Stephenson > <p.stephenson@samsung.com> wrote: > > It's a little bit tangential, but it's always bothered me that the only > > option we have for module builtins of this kind is to import the into > > the command namespace under the standard name, trashing the use of the > > system-standard utility your code may elsewhere depend on That is, you > > can use "command ln" if you need to, but the point is in the majority of > > existing code you would never have bothered to do that. > > > > We made special arrangements for (z)stat but that really doesn't scale > > well. > > > > Apart from (z)stat, most of the builtins that look like standard utilies > > are only there for special cases, e.g. for some reason you can't get to > > the file system where they live, in which case there's no real problem. > > But for uses like this there potentially is. > > Actually all the builtins foo in zsh/files are also available as zf_foo. You're right, that's another, different, special case. But it's the one that probably matters the most in practice. pws ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-09 9:02 ` Peter Stephenson @ 2015-01-09 12:51 ` Peter Stephenson 2015-01-09 13:35 ` Peter Stephenson 0 siblings, 1 reply; 20+ messages in thread From: Peter Stephenson @ 2015-01-09 12:51 UTC (permalink / raw) To: Zsh hackers list On Fri, 9 Jan 2015 09:02:38 +0000 Peter Stephenson <p.stephenson@samsung.com> wrote: > On Fri, 9 Jan 2015 03:51:01 +0100 > Mikael Magnusson <mikachu@gmail.com> wrote: > > Actually all the builtins foo in zsh/files are also available as zf_foo. > > You're right, that's another, different, special case. But it's the one > that probably matters the most in practice. Hey, I made this work! Well, I assume it was me... % zmodload -m -F zsh/files b:zf_\* % zmodload -lF zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync +b:zf_chgrp +b:zf_chown +b:zf_ln +b:zf_mkdir +b:zf_mv +b:zf_rm +b:zf_rmdir +b:zf_sync I feel quite smart, now. Probably worth mentioning in the zsh/files doc. pws ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Re: Insecure tempfile creation 2015-01-09 12:51 ` Peter Stephenson @ 2015-01-09 13:35 ` Peter Stephenson 0 siblings, 0 replies; 20+ messages in thread From: Peter Stephenson @ 2015-01-09 13:35 UTC (permalink / raw) To: Zsh hackers list On Fri, 9 Jan 2015 12:51:05 +0000 Peter Stephenson <p.stephenson@samsung.com> wrote: > Probably worth mentioning in the zsh/files doc. diff --git a/Doc/Zsh/mod_files.yo b/Doc/Zsh/mod_files.yo index 5dbdae7..90e9884 100644 --- a/Doc/Zsh/mod_files.yo +++ b/Doc/Zsh/mod_files.yo @@ -10,7 +10,10 @@ all features now required by relevant standards committees. For all commands, a variant beginning tt(zf_) is also available and loaded automatically. Using the features capability of zmodload will let you load -only those names you want. +only those names you want. Note that it's possible to load only the +builtins with zsh-specific names using the following command: + +example(zmodload -m -F zsh/files b:zf_\*) The commands loaded by default are: pws ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2015-01-09 13:35 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-12-22 20:36 Insecure tempfile creation Daniel Shahaf 2014-12-22 22:01 ` Mikael Magnusson 2014-12-23 2:07 ` Bart Schaefer 2014-12-28 6:30 ` Bart Schaefer 2014-12-28 7:44 ` [PATCH] " Bart Schaefer 2014-12-28 8:41 ` Bart Schaefer 2014-12-29 0:49 ` Daniel Shahaf 2014-12-29 4:01 ` Bart Schaefer 2015-01-07 22:03 ` Daniel Shahaf 2015-01-08 6:22 ` Bart Schaefer 2015-01-08 6:48 ` Danek Duvall 2015-01-08 8:08 ` Bart Schaefer 2015-01-08 14:10 ` Daniel Shahaf 2015-01-08 14:24 ` Peter Stephenson 2015-01-08 16:35 ` Ray Andrews 2015-01-08 17:40 ` Peter Stephenson 2015-01-09 2:51 ` Mikael Magnusson 2015-01-09 9:02 ` Peter Stephenson 2015-01-09 12:51 ` Peter Stephenson 2015-01-09 13:35 ` Peter Stephenson
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).