| Ticket UUID: | a63f5a4fed23469bf1e1caaaf674b9dc765dd2ce | ||
| Title: | Safe interp gets the parent's -errorinfo and -errorstack through a failing alias | ||
| Type: | Bug | Created on: | 2026-10-17 10:51:11 |
| Submitter: | serhiy.storchaka | Assigned to: | jan.nijtmans |
| Subsystem: | 20. [interp] | Severity: | Important |
| Priority: | 5 Medium | Last modified: | 2026-10-20 21:24:41 |
| Status: | Closed | Closed by: | jan.nijtmans |
| Resolution: | Fixed | Closed on: | 2026-10-20 21:24:41 |
| Version: | 8.6.18, 9.0.5, 9.1.0 | ||
| Description: | ||||
|
When a command in a safe interpreter is an alias to a proc in a trusted parent and that proc fails, the full -errorinfo and -errorstack of the parent are copied into the safe interpreter. The safe interpreter then sees the parent's proc names, the text of their bodies, file names of sourced scripts and, through -errorstack, the actual argument values of every parent proc on the call stack.
proc GetPassword {user} {return hunter2}
proc VerifyPassword {user pw} {error "access denied"}
proc LoginAlias {user} {VerifyPassword $user [GetPassword $user]}
set s [interp create -safe]
interp alias $s login {} LoginAlias
puts [interp eval $s {
catch {login alice} msg opts
list $::errorInfo [dict get $opts -errorstack]
}]
Actual output (9.1, 9.0, 8.6):
{access denied
while executing
"error "access denied""
(procedure "VerifyPassword" line 1)
invoked from within
"VerifyPassword $user [GetPassword $user]"
(procedure "LoginAlias" line 1)
invoked from within
"login alice"} {INNER {returnImm {access denied} {}} CALL {VerifyPassword alice hunter2} CALL {LoginAlias alice}}
Expected: the safe interpreter sees only the error message and its own part of the traceback, as if login were a C command failing with that message:
{access denied
invoked from within
"login alice"} {}
If the alias target does [source] a file and the script fails, the traceback
also contains (file "/full/path/of/the/parent/script.tcl" line N).
Cause: AliasObjCmd in generic/tclInterp.c calls Tcl_TransferResult, which copies the whole return options dictionary (Tcl_GetReturnOptions) of the parent into the child, whether the child is safe or not. The Safe Base avoids this only because its alias procs rethrow with [return -code error $msg]; user-defined aliases get no such protection. A possible fix is to drop -errorinfo and -errorstack (keeping the message, -errorcode and the return code) when the target interpreter is safe and the source is not. This is the knownBug test interp-26.8, one of the tests collected in [219164ffff] (bug 1637, 1999). The errorInfo part has been there at least since 8.4; -errorstack (8.6) made it worse, since it carries argument values. Related: [77f0dbc0f8] (a stale -errorstack from an earlier, already caught error in the parent is also passed through an alias, because Tcl_GetReturnOptions ignores resetErrorStack), [1669424fff] (file names leak into safe interps via [info frame]). | ||||
| User Comments: | ||||
serhiy.storchaka added on 2026-10-17 11:50:46:
Proposed fix in branch safe-interp-no-parent-traceback: Tcl_TransferResult() no longer transfers -errorinfo, -errorstack and -errorline from a trusted interp to a safe one; the message, -errorcode and the return code still pass. The safe interp starts its own traceback at the alias call. knownBug test interp-26.8 now passes, new test interp-26.10; four safe.test tests that expected part of the parent's traceback are updated. This also fixes the safe interp part of [77f0dbc0f8]. It is a behaviour change of a public function, so it is proposed for 9.1 only. jan.nijtmans added on 2026-10-20 21:11:13:
> It is a behaviour change of a public function, so it is proposed for 9.1 only. Since it's a potential security risk, I'm inclined to accept it for 9.0. Just go ahead! jan.nijtmans added on 2026-10-20 21:12:08:
> It is a behaviour change of a public function, so it is proposed for 9.1 only. Since it's a potential security risk, I'm inclined to accept it for 9.0 and 8.6 too. Just go ahead! serhiy.storchaka added on 2026-10-20 21:22:39:
Merged to [24b65a6fb6|trunk], [19a0f244cb|core-9-0-branch] and [cc7f58c2fd|core-8-6-branch]. On 9.0 and 8.6 the expected results of interp-26.10 ( jan.nijtmans added on 2026-10-20 21:24:41:
Please don't forget the changes.md/changes entries | ||||
