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
SIGSEGV (Segmentation fault) instead of TypeError on dumping list of 254 or more objects #402
Comments
I wonder if I've ran across the same thing, when trying to round-trip the sample.json file from the distribution: #!/usr/bin/env python
import sys
import ujson as json
def main():
s = sys.stdin.read()
try:
x1 = json.loads(s)
x2 = json.dumps(x1, indent=True)
json.loads(x2)
except ValueError as e:
# we expect malformed input to cause ValueErrors
# any other exception or crash is interesting
print(repr(e))
if __name__ == '__main__':
main() I ran that like this: I am using ujson 2.0.3, installed via |
I feel like this is a close answer but I can't figure out why it lets you get to 255 instead of segfaulting on 65. If I had to guess, your example from 65 up to 256 is just a standard heap buffer overflow back up into some other memory still owned by your process until you touch a memory segment which is definitely not yours. Weird that it's on such a nice round number though :-(. Really not sure. Putting some notes here the Line 593 in 7c60d47
then each value (something that fails to encode) gets recursively hit on L685 (so nothing is on the encoder and the error is set). Regardless of what happneed to error, ujson loops each item through the encoder calls this function to realloc some space on the encoder (if needed) on L615 which macros over to this guy requests to reallocs the encoder buffer to at least 2 bytes more than whatever you used to have. When you roll around your loop and hit 2^64 (or whatever SYS_MAX is defined on your system), your size value will be 0. The realloc ends up freeing your memory back to the kernel. the next roll around the loop (back at L685) will add a comma using the I think this is a rough simulation of what's going on in Any thoughts? #include <stdio.h>
#include <stddef.h>
int main() {
size_t wanted_buffer = 2;
//initial encoder
char *str;
str = (char *) malloc(wanted_buffer);
// every encoder loop
int i = 0;
// simulating you with 256 or more items
for (i=0; i<256; i++){
wanted_buffer *= 2; // simulating math at 118 oof the TODO on 113 even calls out this scenario
str = (char *) realloc(str, wanted_buffer); // simulating realloc at L128
if (wanted_buffer == 0){
printf("%s, %d\n", "we've now realloc'd to zero without nulling the pointer", i);
}
}
// the 64th through the loop reallocs to size should overflow and end as zero?
// really don't understand how it's getting to 255
// and then we appendUnchecked a comma to a memory region we no longer own
printf("%s\n", "AppendCharUnchecked on a pointer to 'nowhere' that I don't own ");
// simulating the Buffer_AppendCharUnchecked call adding a comma
str[256] = ','; // segfault!
return (0);
} I think taking care of that TODO on line 113 for a more sane memory allocation strategy (rather than doubling the heap size every loop) would be the best course of action. Some decent middle ground to not be potentially realloc forcing a memory copy to a new address and just blindly doubling every time. Thoughts? |
Not sure if it is related but I have started getting a lot of seg faults (daily) v3.0.0
|
This was fixed by #519 and #505. See #505 (comment) for an explanation of what (I think) happened here. |
What did you do?
My sample program tries to make dump a list of python classes, that are not JSON-serializable.
I expect an exception on ujson.dump() call.
But, If list size is smaller than 254 elements, it raises
TypeError
and this is OK.But when array becomes longer, program crashes:
What did you expect to happen?
exception
TypeError
raisesWhat actually happened?
Program crashes with SIGSEGV instead of throwing an
TypeError
exceptionWhat versions are you using?
Please include code that reproduces the issue.
The best reproductions are self-contained scripts with minimal dependencies.
My almost minimal sample to reproduce this crash:
I currenly don't have debug symbols for ujson, so coredump is not very informative:
The text was updated successfully, but these errors were encountered: