-
Notifications
You must be signed in to change notification settings - Fork 746
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
Stack size limit is not enforced #5871
Comments
I agree that the boundaries should be enforced. Off topic, but... |
That's a good point. It could be about Linux user privileges. https://wiki.ubuntu.com/Audio/TheAudioGroup says "As a practical rule of thumb for Debian and Ubuntu systems, there should be no users in the audio group" but then "Exceptions: ... If you're running Jackd and need realtime privileges" which is every SC user as of now. Then: "The risk involved here is that if a malicious or badly written program makes use of these privileges, it can cause the entire system to lock up, or at least become very sluggish." One reading of this is that, if SC requires JACK, then SC needs to avoid excessive memory-consumption scenarios. That suggests another couple of "maybe" but unlikely solutions:
|
I am vaguely aware of privileges and audio on Linux, however - why do we have to run sclang with the same privileges? Is it because scsynth inherits the privileges from the calling process? If so, it seems like it would be worthy to somehow address that, if that's at all possible. |
AFAICS, TempoClock threads need RT priority in Linux (schedRun() and TempoClock::TempoClock()). But I don't know if they really need RT priority (maybe this was just the easiest way at the time the Linux port started). |
Ah, good to know. Maybe this is something to investigate then. |
Environment
Steps to reproduce
Expected vs. actual behavior
This example specifies a maximum stack depth of 200 for the thread.
It then requests 1000 levels of recursion.
Expected: Stack overflow error. (Or even, sclang crash here would be preferable to what I describe below.)
Actual: Recursion completes, returns
n*2
, and prints 2000.Why this is a bad thing: We expect the stack size to protect against infinite recursion. But (at least in Linux), it doesn't. What happens instead is that every recursive iteration allocates a new stack frame (executeMethodWithKeys() line 894 and executeMethod() line 1055), and at this point, there is no stack depth check.
(There is a checkStackOverflow() function, which seems to be called only from a macro, dispatch_opcode. I suspect compiler flags may be disabling this, however. I tried to replace
assert(checkStackOverflow(g, sp));
withif(!checkStackOverflow(g, sp)) { printf("Stack overflow\n"); std::abort(); };
and couldn't get the if branch to activate. That is, there appears to be an attempt to prevent stack overflow but at some point, accidentally, this may have been disabled.)A riskier demonstration of the issue, then, is:
~stackSizeTest.value(inf)
.I'm gonna gently suggest that sclang "expected behavior" should never include disabling the entire system and forcing a hard reboot.
This is a rare circumstance, and admittedly user error. But, part of the schtick of programming for fun is "go ahead, try it, you can't seriously break anything" but SC can't actually claim that -- you can break something by accidental infinite recursion. So I consider this a fairly high severity bug.
The text was updated successfully, but these errors were encountered: