>Number: 189139
>Category: bin
>Synopsis: BUG in jail(8) variable substitution, and PATCH
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Apr 30 19:00:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator: Dirk Engling
>Release: 9.2
>Organization:
>Environment:
>Description:
The variable substitution of FreeBSD's jail tool yields unexpected results when
a parameter has more than one variable to substitute and one of the later
variables needs substitution as well.
>How-To-Repeat:
Consider the simple test case:
$A = "A_${B}_C_${D}";
$B = "BBBBB";
$D = "DDDDD_${E}_FFFFF";
$E = "EEEEE";
bar {
exec.poststart = "touch /tmp/$A";
}
EXPECTED OUTCOME for running "jail -c bar" would be a file with the name
/tmp/A_BBBBB_C_DDDDD_EEEEE_FFFFF to be touched (and, of course, the jail bar
being created).
OBSERVED OUTCOME is a file with the name /tmp/A_BBBDDDDD_EEEEE_FFFFFBB_C_ being
created.
The reason is the way jail(8) resolves recursive substitutions. In
head/usr.sbin/jail/config.c:193 a varoff variable is introduced that handles a
shifting offset for multiple variable substitutions per parameter. This varoff
is updated after each substitution in line 239 to reflect a new offset into the
parameter's string. This ensures that all other variables are substituted at
[their insertion point plus varoff] which is the accumulated length of all
previously substituted variables.
Now in our example, if $A is to be expanded, first ${B} is inserted at offset 2
and varoff becomes 10. When substituting ${D}, the recursion check at line 216
detects that variable $D also needs expansion. It reorders the parameter list,
so that the algorithm works on variable $D now. Then it jumps to find_vars at
line 191 and properly expands DDDDD_${E}_FFFFF to DDDDD_EEEEE_FFFFF.
When the algorithm now returns to expanding $A by entering the loop body again,
it finds a re-set varoff variable leading to (the now expanded) variable $D
being inserted at the offset 5, where the parser initially would find it (the
internal format for $A is approx: { "A__C_", {2, "B"}, {5, "D"}}) and not at
the corrected offset 10.
>Fix:
Get rid of the varoff and replace line 239 with:
[struct cfvar *]vv = v;
while ((vv = STAILQ_NEXT(vv, tq)))
v->pos += vs->len;
to make the offset permanent. Find a patch here
https://erdgeist.org/arts/software/jail/usr.sbin.jail-substitution.patch
>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"