Skip to content
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 variable and printf cause crash #10

Open
JonasOberhauser opened this issue Jan 13, 2021 · 6 comments
Open

Stack variable and printf cause crash #10

JonasOberhauser opened this issue Jan 13, 2021 · 6 comments

Comments

@JonasOberhauser
Copy link

#include <assert.h>
#include <stdio.h>

#define LEN 4

int main()
{ 
    int i = 6;
    printf("%d",i); // works
    char str[LEN] = {'%', 'd', 0};
    printf("%s",str); // crash
    printf(str, i); // would also crash
}

The crash also occurs without the initializer (using some other way to set up str).
The crash does not occur if str is changed to static storage duration (I've tried both using the static keyword and moving it outside the function).

@michaliskok
Copy link
Collaborator

You are right. The reason for this is that external function calls are not currently allowed to read/write any automatic variables. This can be somewhat limiting in some cases, but it does help with some optimizations. I am not very inclined to fix this at the moment, but I will keep the issue open.

@JonasOberhauser
Copy link
Author

Did you add some helpful error message when the user does this? Crashing is a bit unfortunate

@michaliskok
Copy link
Collaborator

(Sorry, I inadvertently closed the issue; reopening.)

I didn't, but will do in the next release. In the meantime, you can apply the following patch. BTW, do you encounter this only for printf(), or you have other external calls too?

diff --git a/src/Execution.cpp b/src/Execution.cpp
index 368f7786..33b4aa1a 100644
--- a/src/Execution.cpp
+++ b/src/Execution.cpp
@@ -4368,6 +4368,10 @@ void Interpreter::callFunction(Function *F,
 
   // Special handling for external functions.
   if (F->isDeclaration()) {
+    auto i = 0u;
+    if (std::any_of(F->arg_begin(), F->arg_end(), [&ArgVals,&i,this](decltype(*F->arg_begin()) a){
+		      ++i; return a.getType()->isPointerTy() && isDynamic(GVTOP(ArgVals[i])); }))
+      WARN_ONCE("printf-automatic", "Calling printf() on non-static variables may lead to crashes!\n");
     GenericValue Result = callExternalFunction (F, ArgVals);
     // Simulate a 'ret' instruction of the appropriate type.
     popStackAndReturnValueToCaller (F->getReturnType (), Result);

@michaliskok michaliskok reopened this Jul 28, 2021
@JonasOberhauser
Copy link
Author

@lilith218 has more experience using external functions, maybe she can comment.

@lilith218
Copy link

hmm this could be similar, if not the same to the one I reported yesterday.
@michaliskok I encountered the crash with printf, sprintf and atoi.

@michaliskok
Copy link
Collaborator

Indeed, this is the same as #26. The reason why the crash also manifests with sprintf as well is that printf is implemented via sprintf in the interpreter.

In general, external functions that manipulate stack variables currently cause crashes. Static variables should be fine, but external calls will only see the initial values of these variables and not any updated values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants