Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
cd2fb090
Commit
cd2fb090
authored
May 14, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth, eth/downloader: prevent hash repeater attack
parent
c1f0d40e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
50 additions
and
15 deletions
+50
-15
downloader.go
eth/downloader/downloader.go
+6
-4
downloader_test.go
eth/downloader/downloader_test.go
+29
-0
queue.go
eth/downloader/queue.go
+11
-9
sync.go
eth/sync.go
+4
-2
No files found.
eth/downloader/downloader.go
View file @
cd2fb090
...
@@ -27,7 +27,7 @@ var (
...
@@ -27,7 +27,7 @@ var (
errLowTd
=
errors
.
New
(
"peer's TD is too low"
)
errLowTd
=
errors
.
New
(
"peer's TD is too low"
)
ErrBusy
=
errors
.
New
(
"busy"
)
ErrBusy
=
errors
.
New
(
"busy"
)
errUnknownPeer
=
errors
.
New
(
"peer's unknown or unhealthy"
)
errUnknownPeer
=
errors
.
New
(
"peer's unknown or unhealthy"
)
e
rrBadPeer
=
errors
.
New
(
"action from bad peer ignored"
)
E
rrBadPeer
=
errors
.
New
(
"action from bad peer ignored"
)
errNoPeers
=
errors
.
New
(
"no peers to keep download active"
)
errNoPeers
=
errors
.
New
(
"no peers to keep download active"
)
ErrPendingQueue
=
errors
.
New
(
"pending items in queue"
)
ErrPendingQueue
=
errors
.
New
(
"pending items in queue"
)
ErrTimeout
=
errors
.
New
(
"timeout"
)
ErrTimeout
=
errors
.
New
(
"timeout"
)
...
@@ -266,9 +266,11 @@ out:
...
@@ -266,9 +266,11 @@ out:
break
break
}
}
}
}
d
.
queue
.
Insert
(
hashPack
.
hashes
)
// Insert all the new hashes, but only continue if got something useful
inserts
:=
d
.
queue
.
Insert
(
hashPack
.
hashes
)
if
!
done
{
if
inserts
==
0
&&
!
done
{
return
ErrBadPeer
}
else
if
!
done
{
activePeer
.
getHashes
(
hash
)
activePeer
.
getHashes
(
hash
)
continue
continue
}
}
...
...
eth/downloader/downloader_test.go
View file @
cd2fb090
...
@@ -336,3 +336,32 @@ func TestNonExistingParentAttack(t *testing.T) {
...
@@ -336,3 +336,32 @@ func TestNonExistingParentAttack(t *testing.T) {
t
.
Fatalf
(
"tester doesn't know about the origin hash"
)
t
.
Fatalf
(
"tester doesn't know about the origin hash"
)
}
}
}
}
// Tests that if a malicious peers keeps sending us repeating hashes, we don't
// loop indefinitely.
func
TestRepeatingHashAttack
(
t
*
testing
.
T
)
{
// Create a valid chain, but drop the last link
hashes
:=
createHashes
(
1000
,
1
)
blocks
:=
createBlocksFromHashes
(
hashes
)
hashes
=
hashes
[
:
len
(
hashes
)
-
1
]
// Try and sync with the malicious node
tester
:=
newTester
(
t
,
hashes
,
blocks
)
tester
.
newPeer
(
"attack"
,
big
.
NewInt
(
10000
),
hashes
[
0
])
errc
:=
make
(
chan
error
)
go
func
()
{
errc
<-
tester
.
sync
(
"attack"
,
hashes
[
0
])
}()
// Make sure that syncing returns and does so with a failure
select
{
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
t
.
Fatalf
(
"synchronisation blocked"
)
case
err
:=
<-
errc
:
if
err
==
nil
{
t
.
Fatalf
(
"synchronisation succeeded"
)
}
}
}
eth/downloader/queue.go
View file @
cd2fb090
...
@@ -122,24 +122,26 @@ func (q *queue) Has(hash common.Hash) bool {
...
@@ -122,24 +122,26 @@ func (q *queue) Has(hash common.Hash) bool {
return
false
return
false
}
}
// Insert adds a set of hashes for the download queue for scheduling.
// Insert adds a set of hashes for the download queue for scheduling, returning
func
(
q
*
queue
)
Insert
(
hashes
[]
common
.
Hash
)
{
// the number of new hashes encountered.
func
(
q
*
queue
)
Insert
(
hashes
[]
common
.
Hash
)
int
{
q
.
lock
.
Lock
()
q
.
lock
.
Lock
()
defer
q
.
lock
.
Unlock
()
defer
q
.
lock
.
Unlock
()
// Insert all the hashes prioritized in the arrival order
// Insert all the hashes prioritized in the arrival order
for
i
,
hash
:=
range
hashes
{
inserts
:=
0
index
:=
q
.
hashCounter
+
i
for
_
,
hash
:=
range
hashes
{
// Skip anything we already have
if
old
,
ok
:=
q
.
hashPool
[
hash
];
ok
{
if
old
,
ok
:=
q
.
hashPool
[
hash
];
ok
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Hash %x already scheduled at index %v"
,
hash
,
old
)
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Hash %x already scheduled at index %v"
,
hash
,
old
)
continue
continue
}
}
q
.
hashPool
[
hash
]
=
index
// Update the counters and insert the hash
q
.
hashQueue
.
Push
(
hash
,
float32
(
index
))
// Highest gets schedules first
q
.
hashCounter
,
inserts
=
q
.
hashCounter
+
1
,
inserts
+
1
q
.
hashPool
[
hash
]
=
q
.
hashCounter
q
.
hashQueue
.
Push
(
hash
,
float32
(
q
.
hashCounter
))
// Highest gets schedules first
}
}
// Update the hash counter for the next batch of inserts
return
inserts
q
.
hashCounter
+=
len
(
hashes
)
}
}
// GetHeadBlock retrieves the first block from the cache, or nil if it hasn't
// GetHeadBlock retrieves the first block from the cache, or nil if it hasn't
...
...
eth/sync.go
View file @
cd2fb090
...
@@ -101,11 +101,13 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
...
@@ -101,11 +101,13 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
case
downloader
.
ErrBusy
:
case
downloader
.
ErrBusy
:
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Synchronisation already in progress"
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Synchronisation already in progress"
)
case
downloader
.
ErrTimeout
:
case
downloader
.
ErrTimeout
,
downloader
.
ErrBadPeer
:
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Removing peer %v
due to sync timeout"
,
peer
.
id
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Removing peer %v
: %v"
,
peer
.
id
,
err
)
pm
.
removePeer
(
peer
)
pm
.
removePeer
(
peer
)
case
downloader
.
ErrPendingQueue
:
case
downloader
.
ErrPendingQueue
:
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
"Synchronisation aborted:"
,
err
)
glog
.
V
(
logger
.
Debug
)
.
Infoln
(
"Synchronisation aborted:"
,
err
)
default
:
default
:
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Synchronisation failed: %v"
,
err
)
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Synchronisation failed: %v"
,
err
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment