Skip to content

runtime: shrinking the stack during a system call may cause a corrupt address #10976

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

Closed
ianlancetaylor opened this issue May 28, 2015 · 2 comments
Milestone

Comments

@ianlancetaylor
Copy link
Contributor

This is a spinoff of #10303 .

In a function like this:

func F() {
var a [10]byte
syscall.Read(0, a[:])
}

a does not escape and is therefore allocated on the stack. The call to syscall.Read may block. If a GC occurs while it is blocking, the GC may decide to shrink the stack. Shrinking the stack will move a. This will cause the read call to corrupt random memory when it finally returns.

This is a supposition based on looking at the code. I have no actual test case.

We do not want to treat pointers to syscall functions as causing the pointers to escape. That would force values into the heap unnecessarily. We know that syscall functions on Unix systems never cause the pointers to escape.

Therefore, we need some way to prevent the stack from shrinking while the function is in a system call. One simple approach would be to also prevent the stack from shrinking while in a cgo call: not shrink the stack if the goroutine status is Gsyscall. I don't think that would be too bad--I doubt many goroutines hang in cgo calls with a large stack.

Anyhow, this issue has to be resolved before the 1.5 release, either by deciding that it is not a problem, or by fixing it.

@ianlancetaylor ianlancetaylor added this to the Go1.5 milestone May 28, 2015
@randall77
Copy link
Contributor

We don't shrink stacks if they are in syscall, so I think this is not a bug.

src/runtime/stack1.go:809
// We can't copy the stack if we're in a syscall.
// The syscall might have pointers into the stack.
if gp.syscallsp != 0 {
return
}

I had some ideas about how to shrink without copying (use a buddy list allocator for stacks). But the complexity seemed unnecessary. The only case it would matter is when the goroutine used a large stack, then popped most of it, then made a syscall.

@ianlancetaylor
Copy link
Contributor Author

Thanks, sorry I missed that.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants