From 389edbdf22e30927937fdabb1fb57d1d82dde55a Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 13 Sep 2024 19:02:06 -0600 Subject: [PATCH] EOFCREATE validation Handle Aux Data in EOF Create w/o validation failures --- core/vm/eips.go | 20 +++++++++++++------- core/vm/eof.go | 11 ++++++++--- core/vm/validate.go | 3 --- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index 18ce837792..194e13a2e2 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -924,22 +924,28 @@ func opReturnContract(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte } ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64()) containerCode := scope.Contract.Container.ContainerCode[idx] - deployedCode := append(containerCode, ret...) - if len(deployedCode) == 0 { + //deployedCode := append(containerCode, ret...) + if len(containerCode) == 0 { return nil, errors.New("nonexistant subcontainer") } // Validate the subcontainer var c Container - if err := c.UnmarshalBinary(deployedCode, true); err != nil { - return nil, err - } - if err := c.ValidateCode(interpreter.tableEOF, true); err != nil { + if err := c.UnmarshalSubContainer(containerCode, false); err != nil { return nil, err } + + // append the auxdata + c.Data = append(c.Data, ret...) if len(c.Data) < c.DataSize { - return nil, errors.New("invalid subcontainer") + return nil, errors.New("incomplete aux 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 retCtx := scope.ReturnStack.Pop() scope.CodeSection = retCtx.Section diff --git a/core/vm/eof.go b/core/vm/eof.go index 7b005ca326..5808fd2c79 100644 --- a/core/vm/eof.go +++ b/core/vm/eof.go @@ -145,10 +145,15 @@ func (c *Container) MarshalBinary() []byte { // UnmarshalBinary decodes an EOF container. 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) { 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) 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 { return fmt.Errorf("%w in sub container %d", err, i) } diff --git a/core/vm/validate.go b/core/vm/validate.go index 5cce0cb004..7f4e759db2 100644 --- a/core/vm/validate.go +++ b/core/vm/validate.go @@ -155,9 +155,6 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable, 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) } - 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 if v, ok := visitedSubcontainers[arg]; ok && v != RefByEOFCreate { return nil, fmt.Errorf("section already referenced, arg :%d", arg)