Nothing Special   »   [go: up one dir, main page]

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

Mac OS: C++ printer segfaults #242

Closed
andreasabel opened this issue Nov 4, 2018 · 1 comment
Closed

Mac OS: C++ printer segfaults #242

andreasabel opened this issue Nov 4, 2018 · 1 comment
Assignees
Milestone

Comments

@andreasabel
Copy link
Member
andreasabel commented Nov 4, 2018

Running bnfc-system-tests, I observed that the C++ AST printer for examples/GF/gf.cf https://github.com/BNFC/bnfc/blob/master/examples/GF/gf.cf segfaults when run on examples/GF/example.gf https://github.com/BNFC/bnfc/blob/master/examples/GF/example.gf .

I do not want to debug this. A brief look into the generated printer shows that it has inline functions and destructive update of a buf_ variable.

" void inline resizeBuffer(void)",
" {",
" char *temp = (char *) malloc(buf_size);",
" if (!temp)",
" {",
" fprintf(stderr, \"Error: Out of memory while attempting to grow buffer!\\n\");",
" exit(1);",
" }",
" if (buf_)",
" {",
" strcpy(temp, buf_);",
" free(buf_);",
" }",
" buf_ = temp;",
" }",
" char *buf_;",
" int cur_, buf_size;",
"};",

I leave this to C++ enthusiasts and fans of pointer manipulations. Happy segfaulting!

$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.0.0
Thread model: posix
@andreasabel
Copy link
Member Author

Ah, I am too good natured, I fixed it anyway.
When you try to strcpy a previously grown buffer buf_ into a buffer temp of BUFFER_INITIAL size, yes, then you segfault on a good operating system.

" buf_size = " ++ nsDefine inPackage "BUFFER_INITIAL" ++ ";",
" resizeBuffer();",
" memset(buf_, 0, buf_size);",
" }",
"",
" void inline resizeBuffer(void)",
" {",
" char *temp = (char *) malloc(buf_size);",
" if (!temp)",
" {",
" fprintf(stderr, \"Error: Out of memory while attempting to grow buffer!\\n\");",
" exit(1);",
" }",
" if (buf_)",
" {",
" strcpy(temp, buf_);",

Good old buffer overrun. Wonder if someone managed to hack machines with bnfc installed through this.

@andreasabel andreasabel self-assigned this Nov 4, 2018
@andreasabel andreasabel added this to the 2.8.2 milestone Nov 4, 2018
andreasabel added a commit that referenced this issue Nov 4, 2018
I sleep better if I do not have to worry about the corner cases which
have not been verified by a theorem prover or static analysis.
andreasabel added a commit that referenced this issue Nov 24, 2019
This regression was introduced in the fix of issue #242 (commit
a065117).  It would cause the C++
generated printer to call resizeBuffer for every string appended to the
buffer, not just when resizing was needed.  So for each call to
bufAppend(char*/String), O(n) bytes were copied, with the complexity
deteriorating to O(n^2).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant