From bc3bffea53a8302abf28301f333e9eaf7abf26da Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 22 Jul 2022 12:35:03 +0300 Subject: [PATCH] native: fix oracle.finish reentrancy bug See neo-project/neo#2795. --- pkg/core/native/native_test/oracle_test.go | 2 +- pkg/core/native/oracle.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/core/native/native_test/oracle_test.go b/pkg/core/native/native_test/oracle_test.go index bc32eadde..dec7ab41d 100644 --- a/pkg/core/native/native_test/oracle_test.go +++ b/pkg/core/native/native_test/oracle_test.go @@ -156,7 +156,7 @@ func TestOracle_Request(t *testing.T) { putOracleRequest(t, helperValidatorInvoker, "url", nil, "handleRecursive", []byte{}, gasForResponse) tx := prepareResponseTx(t, 2) e.AddNewBlock(t, tx) - // e.CheckFault(t, tx.Hash(), "") + e.CheckFault(t, tx.Hash(), "Oracle.finish called from non-entry script") aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application) require.NoError(t, err) require.Equal(t, 2, len(aer[0].Events)) // OracleResponse + Invocation diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index 62ac80b00..330e640a7 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -276,6 +276,12 @@ func (o *Oracle) finish(ic *interop.Context, _ []stackitem.Item) stackitem.Item // FinishInternal processes an oracle response. func (o *Oracle) FinishInternal(ic *interop.Context) error { + if ic.VM.Istack().Len() != 2 { + return errors.New("Oracle.finish called from non-entry script") + } + if ic.Invocations[o.Hash] != 1 { + return errors.New("Oracle.finish called multiple times") + } resp := getResponse(ic.Tx) if resp == nil { return ErrResponseNotFound