Skip to content

Commit

Permalink
feat(sdk/vm): disallow calling internal realms (#3794)
Browse files Browse the repository at this point in the history
continuation of #3774, fixes #2190.
  • Loading branch information
thehowl authored Feb 24, 2025
1 parent 27fd12d commit 300dcfd
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
3 changes: 3 additions & 0 deletions gno.land/pkg/sdk/vm/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ func (msg MsgCall) ValidateBasic() error {
if !gno.IsRealmPath(msg.PkgPath) {
return ErrInvalidPkgPath("pkgpath must be of a realm")
}
if _, isInt := gno.IsInternalPath(msg.PkgPath); isInt {
return ErrInvalidPkgPath("pkgpath must not be of an internal package")
}
if msg.Func == "" { // XXX
return ErrInvalidExpr("missing function to call")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ func TestMsgCall_ValidateBasic(t *testing.T) {
},
expectErr: InvalidPkgPathError{},
},
{
name: "pkgPath should not be an internal path",
msg: MsgCall{
Caller: caller,
PkgPath: "gno.land/r/demo/avl/internal/sort",
Func: funcName,
Args: args,
Send: std.Coins{std.Coin{
Denom: "ugnot",
Amount: 1000,
}},
},
expectErr: InvalidPkgPathError{},
},
{
name: "missing function name to call",
msg: MsgCall{
Expand Down
16 changes: 16 additions & 0 deletions gnovm/pkg/gnolang/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ func IsRealmPath(pkgPath string) bool {
!ReGnoRunPath.MatchString(pkgPath)
}

// IsInternalPath determines whether the given pkgPath refers to an internal
// package, that may not be called directly or imported by packages that don't
// share the same root.
//
// If isInternal is true, base will be set to the root of the internal package,
// which must also be an ancestor or the same path that imports the given
// internal package.
func IsInternalPath(pkgPath string) (base string, isInternal bool) {
// Restrict imports to /internal packages to a package rooted at base.
var suff string
base, suff, isInternal = strings.Cut(pkgPath, "/internal")
// /internal should be either at the end, or be a part: /internal/
isInternal = isInternal && (suff == "" || suff[0] == '/')
return
}

// IsPurePackagePath determines whether the given pkgpath is for a published Gno package.
// It only considers "pure" those starting with gno.land/p/, so it returns false for
// stdlib packages and MsgRun paths.
Expand Down
5 changes: 1 addition & 4 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -4822,10 +4822,7 @@ func tryPredefine(store Store, pkg *PackageNode, last BlockNode, d Decl) (un Nam
panic("cannot import stdlib internal/ package outside of standard library")
}

// Restrict imports to /internal packages to a package rooted at base.
base, suff, isInternal := strings.Cut(d.PkgPath, "/internal")
// /internal should be either at the end, or be a part: /internal/
isInternal = isInternal && (suff == "" || suff[0] == '/')
base, isInternal := IsInternalPath(d.PkgPath)
if isInternal &&
pkg.PkgPath != base &&
!strings.HasPrefix(pkg.PkgPath, base+"/") {
Expand Down

0 comments on commit 300dcfd

Please sign in to comment.