1
GC protection for on-stack objects
2
==================================
10
This document describes GC protection for on-stack objects safe against an
11
irregular stack layout such as stack-smashing protection performs.
17
Working on the previous stack protection strategy, following problem
18
occurs.(the explanation is based on
19
http://lists.sourceforge.jp/pipermail/anthy-dev/2005-August/002272.html[Anthy-dev 2273]
20
by Jun Inoue, and assumes that the stack grows downward).
22
Take a look in following code fragment.
25
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28
exp = "(number->string (* 32 1024))";
34
scm_gc_protect_stack(&stack_start);
36
str_port = scm_make_string_port(exp);
37
obj = scm_read(str_port);
38
obj = SCM_EVAL(obj, SCM_INTERACTION_ENV);
40
scm_gc_unprotect_stack(stack_start);
43
return SCM_STRING_STR(obj);
45
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
The previous strategy assumes that `stack_start` is certainly located at lower
48
than `str_port` and `obj` to cover them on the mark-and-sweep stage. But the
49
actual layout breaks the assumption as follows.
51
At the breakpoint immediately before `scm_gc_protect_stack()` of the code
52
compiled with gcc4 ((GCC) 4.0.1 20050617 (prerelease) (Debian 4.0.0-10)
53
(IA32)), actual stack layout had been reported as follows.
55
----------------------------------------------------------------
57
$6 = (ScmObj *) 0xbfffe7d8
59
$7 = (ScmObj *) 0xbfffe7dc
61
$12 = (void *) 0xbfffe7d0
62
----------------------------------------------------------------
64
This result indicates the storage location order inversion:
66
expected: %esp < &str_port < &stack_start
67
actual: %esp < &stack_start < &str_port
69
So `str_port` is not protected in the case.
75
- Allocate the `stack_start` dummy variable in a separated frame
77
- Ensure that a code fragment that its stack must be protected is certainly
78
executed on the stack grown over the frame containing `stack_start`
80
To accomplish it, a series of macros which turns a function into
81
stack-protected. See following steps to know how to use it.
83
1) Split the code fragment off into a function. No stack protection handling is
87
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89
eval_str(const char *exp)
94
str_port = scm_make_string_port(exp);
95
obj = scm_read(str_port);
96
obj = SCM_EVAL(obj, SCM_INTERACTION_ENV);
97
return SCM_STRING_STR(obj);
99
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
2) Call the function prepared in 1) with the macro `SCM_GC_PROTECTED_CALL()` as
103
follows. The macro handles all of the GC protection issues. Once the function
104
returned, the stack protection is disabled again. To protect another function
105
call, apply the macro to the call.
107
Use `SCM_GC_PROTECTED_CALL_VOID()` instead if the calee function returns
111
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113
const char *exp, *ret;
115
exp = "(number->string (* 32 1024))";
116
SCM_GC_PROTECTED_CALL(ret, const char *, eval_str, (exp));
119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~