-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime: check indirect calls for nosplit #12037
Comments
Just discussed this briefly with @rsc. To summarize the problem this issue is about: the nosplit checker can't follow indirect calls, so it's possible to have a nosplit function indirectly call another nosplit function and as a result overflow the stack guard space. This could cause silent stack corruption, which would be very hard to debug. The options seem to be:
|
I'd be happy with (2). If the runtime is fine with it, I would expect any other package would be fine with it as well. |
I made the following hacky change to find places that violate (2): --- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1409,6 +1409,9 @@ func (s *state) expr(n *Node) *ssa.Value {
case ONAME:
if n.Class() == PFUNC {
// "value" of a function is the address of the function's closure
+ if n.Name.Defn != nil && n.Name.Defn.Func.Pragma&Nosplit != 0 {
+ yyerrorl(n.Pos, "cannot use go:nosplit function as function value")
+ }
sym := funcsym(n.Sym).Linksym()
aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: sym})
return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sb) There are four functions. |
Note that (2) also implies marking all exported functions mustsplit. As for the current problems, I don't see why nilfunc or UnlockOSThread are nosplit. That seems unnecessary to me. (I see why LockOSThread is nosplit, but that's not causing problems.) I do agree that funcPC should be a special case anyway. |
That doesn't work so well for exported functions that are nosplit. In fact, (2) might be rather surprising if you, say, try to make a function value of Can we do a hybrid of (2) and (3)? Do (2) within the runtime, but outside of the runtime disallow indirect calls from nosplit functions and mark functions with indirect calls mustsplit? I see exactly one nosplit function in Google's code base outside of runtime/syscall/cgo. |
Sure. Honestly I'm surprised we recognize nosplit outside of the standard library at all. Maybe that's a mistake. |
See https://go-review.googlesource.com/#/c/10362/.
Is it needed?
The text was updated successfully, but these errors were encountered: