Skip to content

Commit

Permalink
container: Validate binary eACL input in setEACL method
Browse files Browse the repository at this point in the history
Previously `setEACL` method could throw `invalid offset` fault exception
about invalid eACL argument. This message is too generic, may occur in
different places of execution code and doesn't help caller to realize
the reason. To improve user experience, it's worth to check method
arguments before slice instructions.

Pre-check `eACL` slice length in `SetEACL` method implementation and
throw responsive panic message.

Ref nspcc-dev#329.

Signed-off-by: Leonard Lyubich <[email protected]>
  • Loading branch information
cthulhu-rider committed Apr 10, 2023
1 parent 8df64fe commit ec467c9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
7 changes: 7 additions & 0 deletions container/container_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,15 @@ func SetEACL(eACL []byte, signature interop.Signature, publicKey interop.PublicK

// V2 format
// get container ID
lnEACL := len(eACL)
if lnEACL < 2 {
panic("missing version field in eACL BLOB")
}
offset := int(eACL[1])
offset = 2 + offset + 4
if lnEACL < offset+containerIDSize {
panic("missing container ID field in eACL BLOB")
}
containerID := eACL[offset : offset+containerIDSize]

ownerID := getOwnerByID(ctx, containerID)
Expand Down
27 changes: 27 additions & 0 deletions tests/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,33 @@ func TestContainerSetEACL(t *testing.T) {
stackitem.NewByteArray(e.token),
})
c.Invoke(t, expected, "eACL", cnt.id[:])

replaceEACLArg := func(eACL []byte) []interface{} {
res := make([]interface{}, len(setArgs))
copy(res, setArgs)
res[0] = eACL
return res
}

checkInvalidEACL := func(eACL []byte, exception string) {
c.InvokeFail(t, exception, "setEACL", replaceEACLArg(eACL)...)
}

const missingVersionException = "missing version field in eACL BLOB"
const missingContainerException = "missing container ID field in eACL BLOB"

checkInvalidEACL([]byte{}, missingVersionException)
checkInvalidEACL([]byte{0}, missingVersionException)
checkInvalidEACL([]byte{0, 0, 0}, missingContainerException)

const offset = byte(20) // any

// first byte can be any since protobuf is not completely decoded
prefix := append([]byte{0, offset}, make([]byte, offset+4)...)

checkInvalidEACL(prefix, missingContainerException)
checkInvalidEACL(append(prefix, make([]byte, len(cnt.id)-1)...), missingContainerException)
c.Invoke(t, stackitem.Null{}, "setEACL", replaceEACLArg(append(prefix, cnt.id[:]...))...)
}

func TestContainerSizeEstimation(t *testing.T) {
Expand Down

0 comments on commit ec467c9

Please sign in to comment.