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
bd6ed238
Unverified
Commit
bd6ed238
authored
7 years ago
by
Martin Holst Swende
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts/abi: harden unpacking against malicious input
parent
08c5d4dd
master
v1.10.12
v1.10.12-modified
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
4 deletions
+83
-4
unpack.go
accounts/abi/unpack.go
+13
-4
unpack_test.go
accounts/abi/unpack_test.go
+70
-0
No files found.
accounts/abi/unpack.go
View file @
bd6ed238
...
...
@@ -95,6 +95,9 @@ func readFixedBytes(t Type, word []byte) (interface{}, error) {
// iteratively unpack elements
func
forEachUnpack
(
t
Type
,
output
[]
byte
,
start
,
size
int
)
(
interface
{},
error
)
{
if
size
<
0
{
return
nil
,
fmt
.
Errorf
(
"cannot marshal input to array, size is negative (%d)"
,
size
)
}
if
start
+
32
*
size
>
len
(
output
)
{
return
nil
,
fmt
.
Errorf
(
"abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)"
,
len
(
output
),
start
+
32
*
size
)
}
...
...
@@ -181,16 +184,22 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) {
// interprets a 32 byte slice as an offset and then determines which indice to look to decode the type.
func
lengthPrefixPointsTo
(
index
int
,
output
[]
byte
)
(
start
int
,
length
int
,
err
error
)
{
offset
:=
int
(
binary
.
BigEndian
.
Uint64
(
output
[
index
+
24
:
index
+
32
]))
offsetBig
:=
big
.
NewInt
(
0
)
.
SetBytes
(
output
[
index
:
index
+
32
])
if
!
offsetBig
.
IsInt64
()
{
return
0
,
0
,
fmt
.
Errorf
(
"abi offset larger than int64: %v"
,
offsetBig
)
}
offset
:=
int
(
offsetBig
.
Int64
())
if
offset
+
32
>
len
(
output
)
{
return
0
,
0
,
fmt
.
Errorf
(
"abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)"
,
len
(
output
),
offset
+
32
)
}
length
=
int
(
binary
.
BigEndian
.
Uint64
(
output
[
offset
+
24
:
offset
+
32
]))
lengthBig
:=
big
.
NewInt
(
0
)
.
SetBytes
(
output
[
offset
:
offset
+
32
])
if
!
lengthBig
.
IsInt64
()
{
return
0
,
0
,
fmt
.
Errorf
(
"abi length larger than int64: %v"
,
lengthBig
)
}
length
=
int
(
lengthBig
.
Int64
())
if
offset
+
32
+
length
>
len
(
output
)
{
return
0
,
0
,
fmt
.
Errorf
(
"abi: cannot marshal in to go type: length insufficient %d require %d"
,
len
(
output
),
offset
+
32
+
length
)
}
start
=
offset
+
32
//fmt.Printf("LENGTH PREFIX INFO: \nsize: %v\noffset: %v\nstart: %v\n", length, offset, start)
return
}
This diff is collapsed.
Click to expand it.
accounts/abi/unpack_test.go
View file @
bd6ed238
...
...
@@ -683,3 +683,73 @@ func TestUnmarshal(t *testing.T) {
t
.
Fatal
(
"expected error:"
,
err
)
}
}
func
TestOOMMaliciousInput
(
t
*
testing
.
T
)
{
oomTests
:=
[]
unpackTest
{
{
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020"
+
// offset
"0000000000000000000000000000000000000000000000000000000000000003"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Length larger than 64 bits
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020"
+
// offset
"00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Offset very large (over 64 bits)
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000020"
+
// offset
"0000000000000000000000000000000000000000000000000000000000000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Offset very large (below 64 bits)
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000007ffffffffff00020"
+
// offset
"0000000000000000000000000000000000000000000000000000000000000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Offset negative (as 64 bit)
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"000000000000000000000000000000000000000000000000f000000000000020"
+
// offset
"0000000000000000000000000000000000000000000000000000000000000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Negative length
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020"
+
// offset
"000000000000000000000000000000000000000000000000f000000000000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
{
// Very large length
def
:
`[{"type": "uint8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020"
+
// offset
"0000000000000000000000000000000000000000000000007fffffffff000002"
+
// num elems
"0000000000000000000000000000000000000000000000000000000000000001"
+
// elem 1
"0000000000000000000000000000000000000000000000000000000000000002"
,
// elem 2
},
}
for
i
,
test
:=
range
oomTests
{
def
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "outputs": %s}]`
,
test
.
def
)
abi
,
err
:=
JSON
(
strings
.
NewReader
(
def
))
if
err
!=
nil
{
t
.
Fatalf
(
"invalid ABI definition %s: %v"
,
def
,
err
)
}
encb
,
err
:=
hex
.
DecodeString
(
test
.
enc
)
if
err
!=
nil
{
t
.
Fatalf
(
"invalid hex: %s"
+
test
.
enc
)
}
_
,
err
=
abi
.
Methods
[
"method"
]
.
Outputs
.
UnpackValues
(
encb
)
if
err
==
nil
{
t
.
Fatalf
(
"Expected error on malicious input, test %d"
,
i
)
}
}
}
This diff is collapsed.
Click to expand it.
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