diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4edda64d..e99df7a7dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.30.0...HEAD) +## [v0.31.x-sdk-v0.46.11-tf-2](https://github.com/notional-labs/wasmd/tree/release/v0.31.x-sdk-v0.46.x) (2023-04-17) + +[Full Changelog](https://github.com/notional-labs/wasmd/compare/release/v0.31.x-sdk-v0.46.x...provenance-io:wasmd:notional-labs-46.11) + +- Introduced security patch from [CWA-2023-001](https://github.com/CosmWasm/advisories/blob/main/CWAs/CWA-2023-001.md) +- Introduced partial changes from [Cosmwasm](https://github.com/CosmWasm/wasmd/pull/1269) to fix transactions ran by proposals. + ## [v0.30.0](https://github.com/CosmWasm/wasmd/tree/v0.30.0) (2022-12-02) [Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.29.2...v0.30.0) diff --git a/app/app.go b/app/app.go index c8e02be5df..6b71132ba8 100644 --- a/app/app.go +++ b/app/app.go @@ -565,6 +565,7 @@ func NewWasmApp( wasmDir, wasmConfig, availableCapabilities, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), wasmOpts..., ) diff --git a/go.mod b/go.mod index 906834fdef..7a48d4cdb5 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.0-beta.6 - github.com/CosmWasm/wasmvm v1.2.1 + github.com/CosmWasm/wasmvm v1.2.3 github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/cosmos-sdk v0.46.11 github.com/cosmos/gogoproto v1.4.6 diff --git a/go.sum b/go.sum index d14cd3cc98..9bc7d5e892 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmvm v1.2.1 h1:si0tRsRDdUShV0k51Wn6zRKlmj3/WWP9Yr4cLmDTf+8= -github.com/CosmWasm/wasmvm v1.2.1/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= +github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= diff --git a/x/wasm/handler.go b/x/wasm/handler.go index db0f0b0c64..b835c04de4 100644 --- a/x/wasm/handler.go +++ b/x/wasm/handler.go @@ -15,7 +15,7 @@ import ( ) // NewHandler returns a handler for "wasm" type messages. -func NewHandler(k types.ContractOpsKeeper) sdk.Handler { +func NewHandler(k *keeper.Keeper) sdk.Handler { msgServer := keeper.NewMsgServerImpl(k) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index 49e304af4a..ee6a5b2e8a 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -13,8 +13,10 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -654,6 +656,7 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []storetypes.StoreKey) { wasmConfig := types.DefaultWasmConfig() pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams) - srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(types.ModuleName), authkeeper.AccountKeeper{}, bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, tempDir, wasmConfig, AvailableCapabilities) + authority := authtypes.NewModuleAddress(govtypes.ModuleName).String() + srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(types.ModuleName), authkeeper.AccountKeeper{}, bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, tempDir, wasmConfig, AvailableCapabilities, authority) return &srcKeeper, ctx, []storetypes.StoreKey{keyWasm, keyParams} } diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 2f79efde58..ae15f87e93 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -103,6 +103,12 @@ type Keeper struct { maxQueryStackSize uint32 acceptedAccountTypes map[reflect.Type]struct{} accountPruner AccountPruner + authority string +} + +// GetAuthority returns the x/wasm module's authority. +func (k Keeper) GetAuthority() string { + return k.authority } func (k Keeper) getUploadAccessConfig(ctx sdk.Context) types.AccessConfig { diff --git a/x/wasm/keeper/keeper_cgo.go b/x/wasm/keeper/keeper_cgo.go index 16fc215936..a9189328e5 100644 --- a/x/wasm/keeper/keeper_cgo.go +++ b/x/wasm/keeper/keeper_cgo.go @@ -31,6 +31,7 @@ func NewKeeper( homeDir string, wasmConfig types.WasmConfig, availableCapabilities string, + authority string, opts ...Option, ) Keeper { wasmer, err := wasmvm.NewVM(filepath.Join(homeDir, "wasm"), availableCapabilities, contractMemoryLimit, wasmConfig.ContractDebugMode, wasmConfig.MemoryCacheSize) @@ -57,6 +58,7 @@ func NewKeeper( gasRegister: NewDefaultWasmGasRegister(), maxQueryStackSize: types.DefaultMaxQueryStackSize, acceptedAccountTypes: defaultAcceptedAccountTypes, + authority: authority, } keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, keeper) for _, o := range opts { diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index 30b322b9a3..5f6d95ff34 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -753,7 +753,7 @@ func TestInstantiateWithContractFactoryChildQueriesParent(t *testing.T) { // overwrite wasmvm in router router := baseapp.NewMsgServiceRouter() router.SetInterfaceRegistry(keepers.EncodingConfig.InterfaceRegistry) - types.RegisterMsgServer(router, NewMsgServerImpl(NewDefaultPermissionKeeper(keeper))) + types.RegisterMsgServer(router, NewMsgServerImpl(keeper)) keeper.messenger = NewDefaultMessageHandler(router, nil, nil, nil, keepers.EncodingConfig.Marshaler, nil) // overwrite wasmvm in response handler keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper)) diff --git a/x/wasm/keeper/msg_server.go b/x/wasm/keeper/msg_server.go index fb311472d6..ab8c49432e 100644 --- a/x/wasm/keeper/msg_server.go +++ b/x/wasm/keeper/msg_server.go @@ -12,10 +12,10 @@ import ( var _ types.MsgServer = msgServer{} type msgServer struct { - keeper types.ContractOpsKeeper + keeper *Keeper } -func NewMsgServerImpl(k types.ContractOpsKeeper) types.MsgServer { +func NewMsgServerImpl(k *Keeper) types.MsgServer { return &msgServer{keeper: k} } @@ -35,7 +35,9 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - codeID, checksum, err := m.keeper.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission) + policy := m.selectAuthorizationPolicy(msg.Sender) + + codeID, checksum, err := m.keeper.create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission, policy) if err != nil { return nil, err } @@ -70,7 +72,9 @@ func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInst sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds) + policy := m.selectAuthorizationPolicy(msg.Sender) + + contractAddr, data, err := m.keeper.instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds, m.keeper.ClassicAddressGenerator(), policy) if err != nil { return nil, err } @@ -104,7 +108,10 @@ func (m msgServer) InstantiateContract2(goCtx context.Context, msg *types.MsgIns sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - contractAddr, data, err := m.keeper.Instantiate2(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds, msg.Salt, msg.FixMsg) + + policy := m.selectAuthorizationPolicy(msg.Sender) + addrGenerator := PredicableAddressGenerator(senderAddr, msg.Salt, msg.Msg, msg.FixMsg) + contractAddr, data, err := m.keeper.instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds, addrGenerator, policy) if err != nil { return nil, err } @@ -136,7 +143,7 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - data, err := m.keeper.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) + data, err := m.keeper.execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) if err != nil { return nil, err } @@ -167,7 +174,9 @@ func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateC sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - data, err := m.keeper.Migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.Msg) + policy := m.selectAuthorizationPolicy(msg.Sender) + + data, err := m.keeper.migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.Msg, policy) if err != nil { return nil, err } @@ -202,7 +211,9 @@ func (m msgServer) UpdateAdmin(goCtx context.Context, msg *types.MsgUpdateAdmin) sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - if err := m.keeper.UpdateContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr); err != nil { + policy := m.selectAuthorizationPolicy(msg.Sender) + + if err := m.keeper.setContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr, policy); err != nil { return nil, err } @@ -230,7 +241,9 @@ func (m msgServer) ClearAdmin(goCtx context.Context, msg *types.MsgClearAdmin) ( sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), )) - if err := m.keeper.ClearContractAdmin(ctx, contractAddr, senderAddr); err != nil { + policy := m.selectAuthorizationPolicy(msg.Sender) + + if err := m.keeper.setContractAdmin(ctx, contractAddr, senderAddr, nil, policy); err != nil { return nil, err } @@ -243,7 +256,8 @@ func (m msgServer) UpdateInstantiateConfig(goCtx context.Context, msg *types.Msg } ctx := sdk.UnwrapSDKContext(goCtx) - if err := m.keeper.SetAccessConfig(ctx, msg.CodeID, sdk.AccAddress(msg.Sender), *msg.NewInstantiatePermission); err != nil { + policy := m.selectAuthorizationPolicy(msg.Sender) + if err := m.keeper.setAccessConfig(ctx, msg.CodeID, sdk.AccAddress(msg.Sender), *msg.NewInstantiatePermission, policy); err != nil { return nil, err } ctx.EventManager().EmitEvent(sdk.NewEvent( @@ -254,3 +268,10 @@ func (m msgServer) UpdateInstantiateConfig(goCtx context.Context, msg *types.Msg return &types.MsgUpdateInstantiateConfigResponse{}, nil } + +func (m msgServer) selectAuthorizationPolicy(actor string) AuthorizationPolicy { + if actor == m.keeper.GetAuthority() { + return GovAuthorizationPolicy{} + } + return DefaultAuthorizationPolicy{} +} diff --git a/x/wasm/keeper/options_test.go b/x/wasm/keeper/options_test.go index b04198710a..ed1c347d2e 100644 --- a/x/wasm/keeper/options_test.go +++ b/x/wasm/keeper/options_test.go @@ -9,6 +9,7 @@ import ( vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/stretchr/testify/assert" @@ -104,7 +105,8 @@ func TestConstructorOptions(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, spec.srcOpt) + authority := authtypes.NewModuleAddress(govtypes.ModuleName).String() + k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, authority, spec.srcOpt) spec.verify(t, k) }) } diff --git a/x/wasm/keeper/test_common.go b/x/wasm/keeper/test_common.go index 23f7e01259..760cf36fbd 100644 --- a/x/wasm/keeper/test_common.go +++ b/x/wasm/keeper/test_common.go @@ -394,12 +394,13 @@ func createTestInput( tempDir, wasmConfig, availableCapabilities, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), opts..., ) keeper.SetParams(ctx, types.DefaultParams()) // add wasm handler so we can loop-back (contracts calling contracts) contractKeeper := NewDefaultPermissionKeeper(&keeper) - types.RegisterMsgServer(router, NewMsgServerImpl(contractKeeper)) + types.RegisterMsgServer(router, NewMsgServerImpl(&keeper)) am := module.NewManager( // minimal module set that we use for message/ query tests bank.NewAppModule(appCodec, bankKeeper, accountKeeper), @@ -407,7 +408,7 @@ func createTestInput( distribution.NewAppModule(appCodec, distKeeper, accountKeeper, bankKeeper, stakingKeeper), ) am.RegisterServices(module.NewConfigurator(appCodec, msgRouter, querier)) - types.RegisterMsgServer(msgRouter, NewMsgServerImpl(NewDefaultPermissionKeeper(keeper))) + types.RegisterMsgServer(msgRouter, NewMsgServerImpl(&keeper)) types.RegisterQueryServer(querier, NewGrpcQuerier(appCodec, keys[types.ModuleName], keeper, keeper.queryGasLimit)) govRouter := govv1beta1.NewRouter(). diff --git a/x/wasm/module.go b/x/wasm/module.go index 5d91b519eb..b8f21e9bb9 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -129,7 +129,7 @@ func NewAppModule( } func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(keeper.NewDefaultPermissionKeeper(am.keeper))) + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), NewQuerier(am.keeper)) m := keeper.NewMigrator(*am.keeper) @@ -148,7 +148,7 @@ func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // Route returns the message routing key for the wasm module. func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(RouterKey, NewHandler(keeper.NewDefaultPermissionKeeper(am.keeper))) + return sdk.NewRoute(RouterKey, NewHandler(am.keeper)) } // QuerierRoute returns the wasm module's querier route name.