tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Possible "new" redirect style for /bin/sh (needs a name)



Hello Robert,

On Sat, Apr 10, 2021 at 08:34:51AM +0700, Robert Elz wrote:
> Sometime, in the now moderately distant past, I recall a notable
> NetBSD developer say that the one useful thing missing from our /bin/sh
> that is present in bash & ksh (and zsh) is {var}>whatever type redirects.
> 
> I have been hesitant about implementing this as I could not think
> of a way (in our shell) to do it safely.
> 
> For anyone unaware, this kind of redirect does the redirect, picks
> a "random" fd, ("random" here just means unknown to the script writer, no
> mathematical randomness properties implied, or implemented) and assigns
> its value to the variable named in the braces.   It is particularly useful
> in functions, where a temporary fd is needed, but where it is unknown
> which fds the application might be using (so the function cannot simply
> safely pick fd=7 (or some other number) and hope).
> 
> Our problem is what "random" fd to assign?    Traditionally, shells
> have simply assigned anything (currently unused) >= 10, and with ksh
> that works fine, as users are only allowed to use (in redirects) fds
> between 0 and 9 (incl) - that is, a single digit.   We don't have that
> limitation, so I have always been worried about how to avoid
> 
> 	exec {var}>/some/hidden/file	; # sh assigns var=10 and fd 10 is open
> 	# some arbitrary amount of intervening code here
> 	exec 10>/other/public/file
> 
> 	echo secret text > ${var}
> 
> I could never see a way to stop that from happening.  Other shell internal
> use fd's the shell can simply renumber when the user attempts to use the
> same fd for the script's use (and we do that) - but that's not possible here
> as we cannot tell what the user might have done with the contents of var
> 
> Eg:
> 	exec {var}>/some/hidden/file
> 	echo $var >/some/hidden/fd-number
> 
> and then later
> 
> 	echo whatever > "$(cat /some/hidden/fd-number)"
> 
> This kind of thing might seem particularly perverse, but it is perfectly
> legal, and should work, and be safe.
> 
> I am still unable to think of a way to make this safe ... bash is currently
> the only shell that has this problem, and there it is simply ignored.
> It hasn't caused any reported problems, but that may be because most
> shells still don't allow explicit use of an fd >= 10, so most scripts
> simply don't attempt to do that.

Wouldn't be possible to flag "var" as being a "fd_var" (or whatever) and
disallow a direct or indirect redirection to a fd that is superior or
equal to some upper limit (see below) that is the minimum value
of the range reserved for this kind of redirection, unless it is given
as "$var"?

> 
> Relying on that kind of "works much of the time" has never been good
> enough for me.
> 
> While I still cannot think of a way to automatically handle this, I
> do have a way to allow the script to tell the shell the biggest fd
> it will ever use, after which the shell simply always assigns fds
> bigger than that when using this new kind of redirect.   If the script
> never explicitly uses fds >= 10, then it need do nothing (this is the
> normal case), otherwise it should make some explicit reference to the
> fd in code that is seen by the parser (it doesn't need to actually be
> executed) before the {var}> type redirect is first executed.
> 

Why not simply use fd the same way as memory is used, i.e. starting by both
ends, to have variable stack and heap concurrently using the mem. 

Starting from 0 and increasing will be
the range to be used directly by the script; starting from the end and
decreasing will be the range for {var}>/some/file. The variable lower bound of
the latter will be the limit to test against in the above security
concern you have mentioned.


FWIW.

Best regards,
-- 
        Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
                     http://www.kergis.com/
                    http://kertex.kergis.com/
                       http://www.sbfa.fr/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Home | Main Index | Thread Index | Old Index