From e9ef7d5ab42a8f896be92b9ed2c1818044b38f04 Mon Sep 17 00:00:00 2001 From: cypherpunks Date: Sat, 18 Aug 2018 16:54:09 +0000 Subject: [PATCH 1/4] test/protover: remove version zero from tests This isn't legal according to dir-spec.txt. We can write separate tests for it if the spec is changed to make it legal. --- src/test/test_protover.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/test_protover.c b/src/test/test_protover.c index 0948cd5640..fb374c728b 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -290,13 +290,13 @@ test_protover_all_supported(void *arg) tor_free(msg); /* We shouldn't be able to DoS ourselves parsing a large range. */ - tt_assert(! protover_all_supported("Sleen=0-2147483648", &msg)); - tt_str_op(msg, OP_EQ, "Sleen=0-2147483648"); + tt_assert(! protover_all_supported("Sleen=1-2147483648", &msg)); + tt_str_op(msg, OP_EQ, "Sleen=1-2147483648"); tor_free(msg); /* This case is allowed. */ - tt_assert(! protover_all_supported("Sleen=0-4294967294", &msg)); - tt_str_op(msg, OP_EQ, "Sleen=0-4294967294"); + tt_assert(! protover_all_supported("Sleen=1-4294967294", &msg)); + tt_str_op(msg, OP_EQ, "Sleen=1-4294967294"); tor_free(msg); /* If we get a (barely) valid (but unsupported list, we say "yes, that's @@ -313,7 +313,7 @@ test_protover_all_supported(void *arg) /* If we get a completely unparseable list, protover_all_supported should * hit a fatal assertion for BUG(entries == NULL). */ tor_capture_bugs_(1); - tt_assert(protover_all_supported("Sleen=0-4294967295", &msg)); + tt_assert(protover_all_supported("Sleen=1-4294967295", &msg)); tor_end_capture_bugs_(); /* Protocol name too long */ @@ -548,11 +548,11 @@ test_protover_vote_roundtrip(void *args) { "Zn=4294967295-1", NULL }, { "Zn=4294967293-4294967295", NULL }, /* Will fail because of 4294967295. */ - { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=0,4294967295", + { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295", NULL }, - { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=0,4294967294", - "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=0,4294967294" }, - { "Zu16=0,65536", "Zu16=0,65536" }, + { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967294", + "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=1,4294967294" }, + { "Zu16=1,65536", "Zu16=1,65536" }, { "N-1=1,2", "N-1=1-2" }, { "-1=4294967295", NULL }, { "-1=3", "-1=3" }, @@ -581,9 +581,9 @@ test_protover_vote_roundtrip(void *args) { "Sleen=1-501", "Sleen=1-501" }, { "Sleen=1-65537", NULL }, /* Both C/Rust implementations should be able to handle this mild DoS. */ - { "Sleen=0-2147483648", NULL }, + { "Sleen=1-2147483648", NULL }, /* Rust tests are built in debug mode, so ints are bounds-checked. */ - { "Sleen=0-4294967295", NULL }, + { "Sleen=1-4294967295", NULL }, }; unsigned u; smartlist_t *votes = smartlist_new(); From b88a2f28ae3845927021edb7ba87063bedf9bfa5 Mon Sep 17 00:00:00 2001 From: cypherpunks Date: Sat, 18 Aug 2018 20:05:19 +0000 Subject: [PATCH 2/4] rust/protover: remove version zero from tests This isn't legal according to dir-spec.txt. We can write separate tests for it if the spec is changed to make it legal. --- src/rust/protover/protoset.rs | 15 +++++++-------- src/rust/protover/protover.rs | 4 ++-- src/rust/protover/tests/protover.rs | 14 +++++++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/rust/protover/protoset.rs b/src/rust/protover/protoset.rs index 027dfba203..7e6f606a2f 100644 --- a/src/rust/protover/protoset.rs +++ b/src/rust/protover/protoset.rs @@ -520,7 +520,6 @@ mod test { test_protoset_contains_versions!(&[1], "1"); test_protoset_contains_versions!(&[1, 2], "1,2"); test_protoset_contains_versions!(&[1, 2, 3], "1-3"); - test_protoset_contains_versions!(&[0, 1], "0-1"); test_protoset_contains_versions!(&[1, 2, 5], "1-2,5"); test_protoset_contains_versions!(&[1, 3, 4, 5], "1,3-5"); test_protoset_contains_versions!(&[42, 55, 56, 57, 58], "42,55-58"); @@ -587,9 +586,9 @@ mod test { #[test] fn test_protoset_contains() { - let protoset: ProtoSet = ProtoSet::from_slice(&[(0, 5), (7, 9), (13, 14)]).unwrap(); + let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 5), (7, 9), (13, 14)]).unwrap(); - for x in 0..6 { assert!(protoset.contains(&x), format!("should contain {}", x)); } + for x in 1..6 { assert!(protoset.contains(&x), format!("should contain {}", x)); } for x in 7..10 { assert!(protoset.contains(&x), format!("should contain {}", x)); } for x in 13..15 { assert!(protoset.contains(&x), format!("should contain {}", x)); } @@ -599,10 +598,10 @@ mod test { } #[test] - fn test_protoset_contains_0_3() { - let protoset: ProtoSet = ProtoSet::from_slice(&[(0, 3)]).unwrap(); + fn test_protoset_contains_1_3() { + let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 3)]).unwrap(); - for x in 0..4 { assert!(protoset.contains(&x), format!("should contain {}", x)); } + for x in 1..4 { assert!(protoset.contains(&x), format!("should contain {}", x)); } } macro_rules! assert_protoset_from_vec_contains_all { @@ -622,8 +621,8 @@ mod test { } #[test] - fn test_protoset_from_vec_0_315() { - assert_protoset_from_vec_contains_all!(0, 1, 2, 3, 15); + fn test_protoset_from_vec_1_315() { + assert_protoset_from_vec_contains_all!(1, 2, 3, 15); } #[test] diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs index 17a8d60ec6..12ede53e5b 100644 --- a/src/rust/protover/protover.rs +++ b/src/rust/protover/protover.rs @@ -867,10 +867,10 @@ mod test { #[test] fn test_protoentry_all_supported_unsupported_low_version() { - let protocols: UnvalidatedProtoEntry = "Cons=0-1".parse().unwrap(); + let protocols: UnvalidatedProtoEntry = "HSIntro=2-3".parse().unwrap(); let unsupported: Option = protocols.all_supported(); assert_eq!(true, unsupported.is_some()); - assert_eq!("Cons=0", &unsupported.unwrap().to_string()); + assert_eq!("HSIntro=2", &unsupported.unwrap().to_string()); } #[test] diff --git a/src/rust/protover/tests/protover.rs b/src/rust/protover/tests/protover.rs index 2db01a1634..59a4b5a8a0 100644 --- a/src/rust/protover/tests/protover.rs +++ b/src/rust/protover/tests/protover.rs @@ -106,10 +106,10 @@ fn protocol_all_supported_with_unsupported_versions() { #[test] fn protocol_all_supported_with_unsupported_low_version() { - let protocols: UnvalidatedProtoEntry = "Cons=0-1".parse().unwrap(); + let protocols: UnvalidatedProtoEntry = "HSIntro=2-3".parse().unwrap(); let unsupported: Option = protocols.all_supported(); assert_eq!(true, unsupported.is_some()); - assert_eq!("Cons=0", &unsupported.unwrap().to_string()); + assert_eq!("HSIntro=2", &unsupported.unwrap().to_string()); } #[test] @@ -354,18 +354,18 @@ fn protover_all_supported_should_exclude_some_versions_and_entire_protocols() { #[test] fn protover_all_supported_should_not_dos_anyones_computer() { - let proto: UnvalidatedProtoEntry = "Sleen=0-2147483648".parse().unwrap(); + let proto: UnvalidatedProtoEntry = "Sleen=1-2147483648".parse().unwrap(); let result: String = proto.all_supported().unwrap().to_string(); - assert_eq!(result, "Sleen=0-2147483648".to_string()); + assert_eq!(result, "Sleen=1-2147483648".to_string()); } #[test] fn protover_all_supported_should_not_dos_anyones_computer_max_versions() { - let proto: UnvalidatedProtoEntry = "Sleen=0-4294967294".parse().unwrap(); + let proto: UnvalidatedProtoEntry = "Sleen=1-4294967294".parse().unwrap(); let result: String = proto.all_supported().unwrap().to_string(); - assert_eq!(result, "Sleen=0-4294967294".to_string()); + assert_eq!(result, "Sleen=1-4294967294".to_string()); } #[test] @@ -388,7 +388,7 @@ fn protover_unvalidatedprotoentry_should_err_entirely_unparseable_things() { #[test] fn protover_all_supported_over_maximum_limit() { - let proto: Result = "Sleen=0-4294967295".parse(); + let proto: Result = "Sleen=1-4294967295".parse(); assert_eq!(Err(ProtoverError::ExceedsMax), proto); } From 03c4d0ab9cfb60ba036bb8e5fe980a5bd2551f7d Mon Sep 17 00:00:00 2001 From: cypherpunks Date: Wed, 12 Sep 2018 02:14:29 +0000 Subject: [PATCH 3/4] rust/protover: fix check for overlapping ranges Closes ticket 27649. Bugfix on e6625113c98c281b0a649598d7daa347c28915e9. --- changes/bug27649 | 4 ++++ src/rust/protover/protoset.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changes/bug27649 diff --git a/changes/bug27649 b/changes/bug27649 new file mode 100644 index 0000000000..6498e961e1 --- /dev/null +++ b/changes/bug27649 @@ -0,0 +1,4 @@ + o Minor bugfixes (rust): + - The protover rewrite in #24031 allowed repeated votes from the same + voter for the same protocol version to be counted multiple times in + protover_compute_vote(). Bugfix on 0.3.3.5-rc; fixes bug 27649. diff --git a/src/rust/protover/protoset.rs b/src/rust/protover/protoset.rs index 7e6f606a2f..b99e1a99f7 100644 --- a/src/rust/protover/protoset.rs +++ b/src/rust/protover/protoset.rs @@ -174,7 +174,7 @@ impl ProtoSet { if low == u32::MAX || high == u32::MAX { return Err(ProtoverError::ExceedsMax); } - if low < last_high { + if low <= last_high { return Err(ProtoverError::Overlap); } else if low > high { return Err(ProtoverError::LowGreaterThanHigh); From 4fa46fca8e71e085883dab6183df498759bc439f Mon Sep 17 00:00:00 2001 From: cypherpunks Date: Wed, 12 Sep 2018 14:22:31 +0000 Subject: [PATCH 4/4] fixup! changes file --- changes/bug27649 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changes/bug27649 b/changes/bug27649 index 6498e961e1..55bfc3a842 100644 --- a/changes/bug27649 +++ b/changes/bug27649 @@ -1,4 +1,4 @@ o Minor bugfixes (rust): - - The protover rewrite in #24031 allowed repeated votes from the same + - The protover rewrite in 24031 allowed repeated votes from the same voter for the same protocol version to be counted multiple times in - protover_compute_vote(). Bugfix on 0.3.3.5-rc; fixes bug 27649. + protover_compute_vote(). Fixes bug 27649; bugfix on 0.3.3.5-rc.