EOFCREATE validation

Handle Aux Data in EOF Create w/o validation failures
This commit is contained in:
Danno Ferrin 2024-09-13 19:02:06 -06:00
parent 4a4d3b07e4
commit 389edbdf22
3 changed files with 21 additions and 13 deletions

View file

@ -924,22 +924,28 @@ func opReturnContract(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
} }
ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
containerCode := scope.Contract.Container.ContainerCode[idx] containerCode := scope.Contract.Container.ContainerCode[idx]
deployedCode := append(containerCode, ret...) //deployedCode := append(containerCode, ret...)
if len(deployedCode) == 0 { if len(containerCode) == 0 {
return nil, errors.New("nonexistant subcontainer") return nil, errors.New("nonexistant subcontainer")
} }
// Validate the subcontainer // Validate the subcontainer
var c Container var c Container
if err := c.UnmarshalBinary(deployedCode, true); err != nil { if err := c.UnmarshalSubContainer(containerCode, false); err != nil {
return nil, err
}
if err := c.ValidateCode(interpreter.tableEOF, true); err != nil {
return nil, err return nil, err
} }
// append the auxdata
c.Data = append(c.Data, ret...)
if len(c.Data) < c.DataSize { if len(c.Data) < c.DataSize {
return nil, errors.New("invalid subcontainer") return nil, errors.New("incomplete aux data")
} }
c.DataSize = len(c.Data) c.DataSize = len(c.Data)
// probably unneeded as subcontainers are deeply validated
if err := c.ValidateCode(interpreter.tableEOF, false); err != nil {
return nil, err
}
// Restore context // Restore context
retCtx := scope.ReturnStack.Pop() retCtx := scope.ReturnStack.Pop()
scope.CodeSection = retCtx.Section scope.CodeSection = retCtx.Section

View file

@ -145,10 +145,15 @@ func (c *Container) MarshalBinary() []byte {
// UnmarshalBinary decodes an EOF container. // UnmarshalBinary decodes an EOF container.
func (c *Container) UnmarshalBinary(b []byte, isInitcode bool) error { func (c *Container) UnmarshalBinary(b []byte, isInitcode bool) error {
return c.unmarshalSubContainer(b, isInitcode, true) return c.unmarshalContainer(b, isInitcode, true)
} }
func (c *Container) unmarshalSubContainer(b []byte, isInitcode bool, topLevel bool) error { // UnmarshalSubContainer decodes an EOF container that is container in another container
func (c *Container) UnmarshalSubContainer(b []byte, isInitcode bool) error {
return c.unmarshalContainer(b, isInitcode, false)
}
func (c *Container) unmarshalContainer(b []byte, isInitcode bool, topLevel bool) error {
if !hasEOFMagic(b) { if !hasEOFMagic(b) {
return fmt.Errorf("%w: want %x", ErrInvalidMagic, eofMagic) return fmt.Errorf("%w: want %x", ErrInvalidMagic, eofMagic)
} }
@ -294,7 +299,7 @@ func (c *Container) unmarshalSubContainer(b []byte, isInitcode bool, topLevel bo
} }
c := new(Container) c := new(Container)
end := min(idx+size, len(b)) end := min(idx+size, len(b))
if err := c.unmarshalSubContainer(b[idx:end], isInitcode, false); err != nil { if err := c.unmarshalContainer(b[idx:end], isInitcode, false); err != nil {
if topLevel { if topLevel {
return fmt.Errorf("%w in sub container %d", err, i) return fmt.Errorf("%w in sub container %d", err, i)
} }

View file

@ -155,9 +155,6 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable,
if ct := container.ContainerSections[arg]; len(ct.Data) != ct.DataSize { if ct := container.ContainerSections[arg]; len(ct.Data) != ct.DataSize {
return nil, fmt.Errorf("%w: container %d, have %d, claimed %d, pos %d", ErrEOFCreateWithTruncatedSection, arg, len(ct.Data), ct.DataSize, i) return nil, fmt.Errorf("%w: container %d, have %d, claimed %d, pos %d", ErrEOFCreateWithTruncatedSection, arg, len(ct.Data), ct.DataSize, i)
} }
if _, ok := visitedSubcontainers[arg]; ok {
return nil, fmt.Errorf("section already referenced, arg :%d", arg)
}
// We need to store per subcontainer how it was referenced // We need to store per subcontainer how it was referenced
if v, ok := visitedSubcontainers[arg]; ok && v != RefByEOFCreate { if v, ok := visitedSubcontainers[arg]; ok && v != RefByEOFCreate {
return nil, fmt.Errorf("section already referenced, arg :%d", arg) return nil, fmt.Errorf("section already referenced, arg :%d", arg)