Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 19.  Multiple Interpreters and Safe-Tcl


You must be aware of Tcl parsing and substitutions when commands are invoked in other interpreters. There are three cases corresponding to interp eval, interp invokehidden, and command aliases.

With interp eval the command is subject to a complete round of parsing and substitutions in the target interpreter. This occurs after the parsing and substitutions for the interp eval command itself. In addition, if you pass several arguments to interp eval, those are concatenated before evaluation. This is similar to the way the eval command works as described in Chapter 19. The most reliable way to use interp eval is to construct a list to ensure the command is well structured:

interp eval slave [list cmd arg1 arg2]

With hidden commands, the command and arguments are taken directly from the arguments to interp invokehidden, and there are no substitutions done in the target interpreter. This means that the master has complete control over the command structure, and nothing funny can happen in the other interpreter. For this reason you should not create a list. If you do that, the whole list will be interpreted as the command name! Instead, just pass separate arguments to interp invokehidden and they are passed straight through to the target:

interp invokehidden slave command arg1 arg2


Never eval alias arguments.

With aliases, all the parsing and substitutions occur in the slave before the alias is invoked in the master. The alias implementation should never eval or subst any values it gets from the slave to avoid executing arbitrary code.

For example, suppose there is an alias to open files. The alias does some checking and then invokes the hidden open command. An untrusted script might pass [exit] as the name of the file to open in order to create mischief. The untrusted code is hoping that the master will accidentally eval the filename and cause the application to exit. This attack has nothing to do with opening files; it just hopes for a poor alias implementation. Example 19-6 shows an alias that is not subject to this attack:

Example 19-6 Substitutions and hidden commands.
interp alias slave open {}safeopen slave
proc safeopen {slave filename {mode r}} {
   # do some checks, then...
   interp invokehidden $slave open $filename $mode
interp eval slave {open \[exit\]}

The command in the slave starts out as:

open \[exit\]

The master has to quote the brackets in its interp eval command or else the slave will try to invoke exit because of command substitution. Presumably exit isn't defined, or it is defined to terminate the slave. Once this quoting is done, the value of filename is [exit] and it is not subject to substitutions. It is safe to use $filename in the interp invokehidden command because it is only substituted once, in the master. The hidden open command also gets [exit] as its filename argument, which is never evaluated as a Tcl command.

      Previous section   Next section