-
-
Notifications
You must be signed in to change notification settings - Fork 742
fix: Use ArrayPool instead of ThreadStatic field for serialization #2202
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
base: master
Are you sure you want to change the base?
fix: Use ArrayPool instead of ThreadStatic field for serialization #2202
Conversation
…or when accessing serializer from getter
@dotnet-policy-service agree |
Thank you for identifying this problem and sharing a solution. However, I'm concerned about making it even more possible to nest serializations, because that violates other security measures that this library makes. It's important that serializations not be nested, and in your example that you added in the test, that is a case where a class should not be deserializing its own data, it should be using a converter instead. What is the symptom of what you saw before this fix? Maybe we can make that symptom far more obvious so people understand the problem and fix it properly. |
Thanks. I also thought ThreadStatic should be removed eventually. |
Symptom of nested serialization follows. In the test scenario
The serializer for the
in serial. Therefore, the expected serialized content of
However, while retrieving
When the serialization completes, final contents of buffer is:
This leads data malformation, unable to deserialize data. If nested serialization is a security concern, I believe MessagePack should raise a proper exception. Using thread-local variable to track whether current thread is already serializing/deserializing should be sufficient to detect and prevent unintended nested serialization/deserialization. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a minimum it seems like the thread local store should be cleared of the array while it is in use so that it doesn't get overwritten like that.
There are situations where performing serialization or deserialization in property getter can be useful. However, since
MessagePackSerializer
uses thread-localbyte[]
array, invoking another serialization during serialization can lead to serialization bugs. This PR fixes bug by replacing thread-local field to rentedbyte[]
array fromArrayPool
. This change should not have any significant impact on other behaviours or any performances.The following tables show the results of the
SerializeBenchmark
benchmark.AnswerDeserialize
benchmarks are omitted, and only benchmarks using current version ofMessagePack
(extern aliased asnewmsgpack
) are included, and iteration count and warmup count modified to 10 and 5. The first table presents results before the replacement, and the second table shows results after the change, and table shows performance difference is negligible.