Conversation
e3608fb to
3a59361
Compare
|
Hmm, the macOS Python builds don't like our new PyArrow tests. I think it's because the default stack size for new threads on macOS is quite smaller (512 kiB by default), debug builds might add some stack overhead, and some of our JSON reading tests are multi-threaded. It's a bit unexpected that 512 kiB of stack isn't enough for 300 levels of nesting (the current limit). I'm now trying to make stack consumption a bit smaller still, by removing the functional overhead in |
Hmm, still getting crashes on macOS Python. Does anyone have a macOS machine so as to get a stack trace? |
|
That said, it seems that stack consumption in debug mode on Linux can be huge as well (each nesting level in Perhaps we should just disable these PyArrow tests in debug mode on macOS. |
|
@github-actions crossbow submit wheelcp314* |
This comment was marked as outdated.
This comment was marked as outdated.
|
Ok, the PyArrow tests passed on the macOS wheel builds (in release mode), so regular users will get stack overflow protection. |
|
@taepper Do you want to review this? |
|
Should we also add an array variant in the C++ test, like the Python test has for both object and array? Right now the C++ test only covers nested objects. |
3e4a96c to
9ddab7c
Compare
Good point, I've added a C++ test for this. |
Our JSON parser is inherently recursive, and a crafted JSON document with huge nesting can send it into a stack overflow. Given that real-world JSON files will not have thousands levels of nesting, we limit the JSON nesting to an arbitrary value of 1000.
9ddab7c to
422930f
Compare
|
I've rebased after PR #51038 (migrating the parser to simdjson) was merged. |
|
@github-actions crossbow submit wheelcp314* |
|
@github-actions crossbow submit -g cpp |
|
Revision: 422930f Submitted crossbow builds: ursacomputing/crossbow @ actions-af8e1837a0 |
|
Revision: 422930f Submitted crossbow builds: ursacomputing/crossbow @ actions-c29d6a353c |
taepper
left a comment
There was a problem hiding this comment.
Looks very good! I really like the refactoring of lambdas to explicitly destructing the child data at call sites.
One gap I found is the ConsumeJsonValue method, which has the same recursive behavior as the parser had.
There was a problem hiding this comment.
In this case, we still call a recursive method without any depth limit. Ideally, we want to pass the current depth to ConsumeJsonValue.
This PR definitely already fixes many cases, so whether we want to change ConsumeJsonValue to accept a depth parameter in this same PR is a different question.
Alternatively, we can add a follow-up issue
There was a problem hiding this comment.
Good point, I'll tackle this here.
There was a problem hiding this comment.
We could solve this like in this case:
#51472
where we let simdjson handle the skip by the regular advancing of the iterator
But this would avoid the json validation (beyond structural errors regarding braces [,],{,} which will still be checked), which is probably required at this point
| // An upper bound on the expected nesting depth of a geospatial JSON metadata object | ||
| constexpr int kMaxJsonDepth = 20; |
There was a problem hiding this comment.
Yes, I think that makes sense. Thank you!
| // 100'000 would definitely trigger a stack overflow, validate that the error is | ||
| // detected before that would happen. |
There was a problem hiding this comment.
Note: in debug builds we probably did not run into stack overflows, but simdjson assertions.
simdjson::ondemand::parser also has a depth limit (default 1024), and when development checks are enabled, it will assert and thus possibly abort the program, if we consume objects deeper than that limit:
I did not quite understand the purpose of this limit (other than aborting debug code using the parser). I will open an issue in simdjson to find out a bit more.
Not any change request, but just for context, which we should maybe document somewhere?
|
Ok, so musllinux crashes after ~152 levels of nesting. It seems the thread stack size is 128kiB there, and each level of nesting in |
|
@github-actions crossbow submit wheelcp314* |
|
Revision: e71ab61 Submitted crossbow builds: ursacomputing/crossbow @ actions-379dcb9fd6 |
Rationale for this change
Our JSON parser is inherently recursive, and a crafted JSON document with huge nesting can send it into a stack overflow.
Given that real-world JSON files will not have thousands levels of nesting, we limit the JSON nesting to an arbitrary value of 300.
Are these changes tested?
Yes, by new tests.
Are there any user-facing changes?
This PR contains a "Critical Fix". A crafted JSON document with a large nesting depth could trigger a denial of service through stack overflow.
Was AI used for this PR?
PR code and description written by:
Reviewed before submission by: