VM: Enforce a call depth limit
This commit is contained in:
parent
d8d2174104
commit
143dcafdb7
@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version {
|
|||||||
switch version {
|
switch version {
|
||||||
case network.Version0, network.Version1, network.Version2, network.Version3:
|
case network.Version0, network.Version1, network.Version2, network.Version3:
|
||||||
return Version0
|
return Version0
|
||||||
case network.Version4, network.Version5:
|
case network.Version4, network.Version5, network.Version6:
|
||||||
return Version2
|
return Version2
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||||
|
@ -405,7 +405,7 @@ func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.Toke
|
|||||||
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
||||||
GasLimit: 1_000_000_000,
|
GasLimit: 1_000_000_000,
|
||||||
From: maddr,
|
From: maddr,
|
||||||
}, maddr, 0, 0, 0)
|
})
|
||||||
|
|
||||||
return rt.TotalFilCircSupply()
|
return rt.TotalFilCircSupply()
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ type Runtime struct {
|
|||||||
originNonce uint64
|
originNonce uint64
|
||||||
|
|
||||||
executionTrace types.ExecutionTrace
|
executionTrace types.ExecutionTrace
|
||||||
|
depth uint64
|
||||||
numActorsCreated uint64
|
numActorsCreated uint64
|
||||||
allowInternal bool
|
allowInternal bool
|
||||||
callerValidated bool
|
callerValidated bool
|
||||||
|
@ -38,6 +38,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MaxCallDepth = 4096
|
||||||
|
|
||||||
var log = logging.Logger("vm")
|
var log = logging.Logger("vm")
|
||||||
var actorLog = logging.Logger("actors")
|
var actorLog = logging.Logger("actors")
|
||||||
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
||||||
@ -97,24 +99,37 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime {
|
func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime {
|
||||||
rt := &Runtime{
|
rt := &Runtime{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
vm: vm,
|
vm: vm,
|
||||||
state: vm.cstate,
|
state: vm.cstate,
|
||||||
origin: origin,
|
origin: msg.From,
|
||||||
originNonce: originNonce,
|
originNonce: msg.Nonce,
|
||||||
height: vm.blockHeight,
|
height: vm.blockHeight,
|
||||||
|
|
||||||
gasUsed: usedGas,
|
gasUsed: 0,
|
||||||
gasAvailable: msg.GasLimit,
|
gasAvailable: msg.GasLimit,
|
||||||
numActorsCreated: nac,
|
depth: 0,
|
||||||
|
numActorsCreated: 0,
|
||||||
pricelist: PricelistByEpoch(vm.blockHeight),
|
pricelist: PricelistByEpoch(vm.blockHeight),
|
||||||
allowInternal: true,
|
allowInternal: true,
|
||||||
callerValidated: false,
|
callerValidated: false,
|
||||||
executionTrace: types.ExecutionTrace{Msg: msg},
|
executionTrace: types.ExecutionTrace{Msg: msg},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if parent != nil {
|
||||||
|
rt.gasUsed = parent.gasUsed
|
||||||
|
rt.origin = parent.origin
|
||||||
|
rt.originNonce = parent.originNonce
|
||||||
|
rt.numActorsCreated = parent.numActorsCreated
|
||||||
|
rt.depth = parent.depth + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if rt.depth > MaxCallDepth && rt.NetworkVersion() >= network.Version6 {
|
||||||
|
rt.Abortf(exitcode.SysErrForbidden, "message execution exceeds call depth")
|
||||||
|
}
|
||||||
|
|
||||||
rt.cst = &cbor.BasicIpldStore{
|
rt.cst = &cbor.BasicIpldStore{
|
||||||
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
|
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
|
||||||
Atlas: vm.cst.Atlas,
|
Atlas: vm.cst.Atlas,
|
||||||
@ -148,8 +163,8 @@ type UnsafeVM struct {
|
|||||||
VM *VM
|
VM *VM
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime {
|
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime {
|
||||||
return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac)
|
return vm.VM.makeRuntime(ctx, msg, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
||||||
@ -224,18 +239,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
|||||||
|
|
||||||
st := vm.cstate
|
st := vm.cstate
|
||||||
|
|
||||||
origin := msg.From
|
rt := vm.makeRuntime(ctx, msg, parent)
|
||||||
on := msg.Nonce
|
|
||||||
var nac uint64 = 0
|
|
||||||
var gasUsed int64
|
|
||||||
if parent != nil {
|
|
||||||
gasUsed = parent.gasUsed
|
|
||||||
origin = parent.origin
|
|
||||||
on = parent.originNonce
|
|
||||||
nac = parent.numActorsCreated
|
|
||||||
}
|
|
||||||
|
|
||||||
rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac)
|
|
||||||
if EnableGasTracing {
|
if EnableGasTracing {
|
||||||
rt.lastGasChargeTime = start
|
rt.lastGasChargeTime = start
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user