Fix nil pointer dereference when a failing sub-status has no message - #174
Open
Axisflow wants to merge 1 commit into
Open
Fix nil pointer dereference when a failing sub-status has no message#174Axisflow wants to merge 1 commit into
Axisflow wants to merge 1 commit into
Conversation
TSStatus.Message is optional in the Thrift IDL, so a failing sub-status can
arrive without one. verifySuccesses dereferenced it unconditionally:
if status.Code != SuccessStatus && status.Code != RedirectionRecommend {
buff.WriteString(*status.Message + ";")
}
so a MULTIPLE_ERROR whose sub-statuses carry only codes panics inside the
client, on a response the server is allowed to send. VerifySuccess already
guards the envelope message a few lines below, which is what makes the missing
guard here look like an oversight rather than an assumption.
Fall back to the status code when no message is supplied, so the returned
BatchError still identifies which sub-status failed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Guard the optional
TSStatus.MessageinverifySuccesses(client/utils.go) so afailing sub-status without a message no longer panics inside the client.
Problem
TSStatus.Messageis optional in the Thrift IDL, so a server may return a failingsub-status carrying only a code.
verifySuccessesdereferences it unconditionally:So a
MULTIPLE_ERRORresponse whose sub-statuses have no messages crashes thecaller with
invalid memory address or nil pointer dereference, inside the clientrather than as a returned error. Every
Insert*path reaches this throughVerifySuccess, so a batch insert is enough to trigger it.VerifySuccess, a few lines below in the same file, already guards the envelopemessage the same way:
which is what makes the missing guard in
verifySuccesseslook like an oversightrather than a deliberate assumption.
Present on
main, ondev/1.3, and in the releasedv1.3.7andv2.0.8.Fix
Fall back to the status code when no message is supplied, so the returned
BatchErrorstill identifies which sub-status failed instead of contributing anempty entry:
BatchError.GetStatuses()is unchanged, so callers that inspect the per-tabletstatuses themselves are unaffected.
Verification
Reproduced and verified locally against a
MULTIPLE_ERRORwhose failingsub-status carries only a code:
VerifySuccesspanics withruntime error: invalid memory address or nil pointer dereference*BatchErrorwhose message names the failing codeand whose
GetStatuses()still holds the full sub-status slicego build ./...,go vet ./client/andgo test ./client/pass.make generatewas not run locally (it needs the thrift toolchain); this change does not touch the
generated code.
No test is included in this PR to keep it to the one-line guard. I have the
reproducing test (a
MULTIPLE_ERRORwith a message-less sub-status, which panicswithout the fix) and am happy to add it here or in a follow-up if you would like it
in the suite.
Please also cherry-pick to
dev/1.3The same line is present on
dev/1.3and shipped inv1.3.7, so a fix that landsonly on
mainwill not reach users on the 1.3 line.