-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
models: tolerate empty field names when unpacking binary points #5716
models: tolerate empty field names when unpacking binary points #5716
Conversation
This isn't quite the right way to fix this. A point should never contain fields without a name.
|
Ok, np. I'll fix accordingly. |
@jwilder - should I trim the field name of leading and trailing whitespace before testing for equality with the empty string? |
d350ed9
to
8229b6f
Compare
@jwilder - I have implemented the first two suggestions with this series. I'll investigate what's required to fix the queries and may submit that as a separate series. I am going to leave 930fc42 in the series because the existing code didn't handle the case gracefully (it should have scanned to the end of the value buffer before skipping to the next field). I'll check the result of the CI build later in the night. |
f297c5a
to
116c704
Compare
@jonseymour thanks for this. I'm down with the following changes: (1) check for empty fields in Can you explain why 930fc42 needs to be accepted though? |
@e-dard - the algorithm is just wrong - if the data is corrupt, the existing algorithm an infinite loop is guaranteed, as illustrated by the test cases that begin the series.. With the version I propose, it is guaranteed that the loop will terminate. updated: e.g. if a corrupt point is read from disk with points.NewPointFromBytes then it might read a data structure which has an empty field name. It is true that the API may not create any new points that are corrupt in this way but it possible that either a) old versions of influx wrote corrupt structures to disk or b) some kind of corruption to disk files might result in an invalid structure. It doesn't cost much to write an algorithm that is guaranteed to terminate, so it seems worth doing when the alternative is one that some times enters an infinite loop due to factors outside of programmer control. if necessary, I can write a test case that shows how points.NewPointFromBytes can be used to create an infinite loop inside influxd. |
@jonseymour which test case are you referring to? Could you throw a link my way? Cheers! |
This commit 23be938. A transcript of executing this test, merged into both #5697 (88937ab) and the commit immediately preceding (b8bb32e) is as follows:
|
OK cool, I see. But that test is now irrelevant because you're removing With the changes you have made to I think 930fc42 can be dropped from the PR. Hope that makes sense? |
As I said, i can create a test case with points.NewPointFromBytes (which does not involve any calls to the now deleted points.AddField) method which will force influxd into an infinite loop if you really want me to prove that the algorithm prior to 930fc42 is vulnerable. |
116c704
to
f92a899
Compare
f92a899
to
0186085
Compare
0186085
to
8490c6e
Compare
@e-dard I've created a test case which shows that points.NewPointFromBytes is vulnerable to an infinite loop if corrupt data is read from the binary encoding of the point. Given that it costs so little to protect the system from an infinite loop caused by a data corruption, there seems to be no sound reason not to accept (8490c6e) (which replaces 930fc42). |
To see the vulnerablity, checkout 9b56025 which does not include the fix and then run the tests in the model package. |
|
||
func TestNewPointsRejectsEmptyFieldNames(t *testing.T) { | ||
if _, err := models.NewPoint("foo", nil, models.Fields{"": 1}, time.Now()); err == nil { | ||
t.Fatalf("expected error if field with empty field name is created - empty string") |
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.
nit: the failure message could be something like got nil, expected error
, i.e., it's preferable to write what you got and then what you expected.
@jonseymour Now I see. It wasn't clear to me that this issue relied on a successful call to OK, just a small nit on the test case then squash all these down? |
8490c6e
to
d6bf5fc
Compare
AddField doesn't allow us to report errors, but we need to validate some field names. Since we have to change the interface anyway, we simply insist that all callers use NewPoint, rather than AddField. Per advice from Jason Wilder, see influxdata#5716 (comment) Signed-off-by: Jon Seymour <jon@wildducktheories.com>
@e-dard I have squashed most of the commits in this series. There is one commit for the tests showing the problems that needed to be fixed and another for the fixes. The RHS of the merge commit merges cleanly with the 0.10.0 branch (which is in the form I need it for my production system). I have added a CHANGELOG update. |
9e10d35
to
8879d1d
Compare
I've removed the CHANGELOG.md update until I get a +1. |
@@ -1079,6 +1081,9 @@ func NewPoint(name string, tags Tags, fields Fields, time time.Time) (Point, err | |||
return nil, fmt.Errorf("NaN is an unsupported value for field %s", key) | |||
} | |||
} | |||
if len(key) == 0 { | |||
return nil, fmt.Errorf("All fields must have non-empty names") |
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.
This error text should start be all lowercase.
One small thing, but 👍 otherwise. |
…fields Influx does not support fields with empty names or points with no fields. NewPoint is changed to validate that all field names are non-empty. AddField is removed because we now require that all fields are specified on construction. NewPointFromByte is changed to return an error if a unmarshaled binary point does not have any fields. newFieldsFromBinary is changed to prevent an infinite loop that can arise while attempting to parse corrupt binary point data. TestNewPointsWithBytesWithCorruptData is changed to reflect the change in the behaviour of NewPointFromByte. Signed-off-by: Jon Seymour <jon@wildducktheories.com>
RHS merges cleanly with 0.10.0 maintenance branch. Signed-off-by: Jon Seymour <jon@wildducktheories.com>
8879d1d
to
095a35b
Compare
@jwilder - done. Thanks for the review! |
Note that this series also includes cherry-pick of influxdata#5697. Signed-off-by: Jon Seymour <jon@wildducktheories.com>
095a35b
to
a8877ba
Compare
LGTM. I'll merge this Monday morning @jonseymour |
Thank you, @e-dard |
models: tolerate empty field names when unpacking binary points
Signed-off-by: Jon Seymour <jon@wildducktheories.com>
…d-names-0.10.0 [0.10.2] Backport #5716 to 0.10.0
Prior to #5697 influx crashed with a panic if a binary point contained an empty field name. After #5697, influx entered an infinite loop in the same circumstance. With this commit, we silently elide any field with an empty field name when unmarshaling a binary point. A related PR (#5714) prevents SELECT INTO trying to create binary points with empty field names.