|
@@ -980,3 +980,151 @@ func TestRetrieveFromStore(t *testing.T) {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestIsCorrupted(t *testing.T) {
|
|
|
+ ds, err := randomLocalStore()
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ // Negative test
|
|
|
+ hnd, err := NewHandle("bitseq-test/data/", ds, "test_corrupted", 1024)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if hnd.runConsistencyCheck() {
|
|
|
+ t.Fatalf("Unexpected corrupted for %s", hnd)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := hnd.CheckConsistency(); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ hnd.Set(0)
|
|
|
+ if hnd.runConsistencyCheck() {
|
|
|
+ t.Fatalf("Unexpected corrupted for %s", hnd)
|
|
|
+ }
|
|
|
+
|
|
|
+ hnd.Set(1023)
|
|
|
+ if hnd.runConsistencyCheck() {
|
|
|
+ t.Fatalf("Unexpected corrupted for %s", hnd)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := hnd.CheckConsistency(); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Try real corrupted ipam handles found in the local store files reported by three docker users,
|
|
|
+ // plus a generic ipam handle from docker 1.9.1. This last will fail as well, because of how the
|
|
|
+ // last node in the sequence is expressed (This is true for IPAM handle only, because of the broadcast
|
|
|
+ // address reservation: last bit). This will allow an application using bitseq that runs a consistency
|
|
|
+ // check to detect and replace the 1.9.0/1 old vulnerable handle with the new one.
|
|
|
+ input := []*Handle{
|
|
|
+ &Handle{
|
|
|
+ id: "LocalDefault/172.17.0.0/16",
|
|
|
+ bits: 65536,
|
|
|
+ unselected: 65412,
|
|
|
+ head: &sequence{
|
|
|
+ block: 0xffffffff,
|
|
|
+ count: 3,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xffffffbf,
|
|
|
+ count: 0,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xfe98816e,
|
|
|
+ count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xffffffff,
|
|
|
+ count: 0,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xe3bc0000,
|
|
|
+ count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0,
|
|
|
+ count: 2042,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x1, count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0, count: 0,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ &Handle{
|
|
|
+ id: "LocalDefault/172.17.0.0/16",
|
|
|
+ bits: 65536,
|
|
|
+ unselected: 65319,
|
|
|
+ head: &sequence{
|
|
|
+ block: 0xffffffff,
|
|
|
+ count: 7,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xffffff7f,
|
|
|
+ count: 0,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xffffffff,
|
|
|
+ count: 0,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x2000000,
|
|
|
+ count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0,
|
|
|
+ count: 2039,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x1,
|
|
|
+ count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0,
|
|
|
+ count: 0,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ &Handle{
|
|
|
+ id: "LocalDefault/172.17.0.0/16",
|
|
|
+ bits: 65536,
|
|
|
+ unselected: 65456,
|
|
|
+ head: &sequence{
|
|
|
+ block: 0xffffffff, count: 2,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xfffbffff, count: 0,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0xffd07000, count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0, count: 333,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x40000000, count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0, count: 1710,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x1, count: 1,
|
|
|
+ next: &sequence{
|
|
|
+ block: 0x0, count: 0,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ for idx, hnd := range input {
|
|
|
+ if !hnd.runConsistencyCheck() {
|
|
|
+ t.Fatalf("Expected corrupted for (%d): %s", idx, hnd)
|
|
|
+ }
|
|
|
+ if hnd.runConsistencyCheck() {
|
|
|
+ t.Fatalf("Sequence still marked corrupted (%d): %s", idx, hnd)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|