Skip to content

Commit

Permalink
o/snapstate: more fully validate components when installing them from…
Browse files Browse the repository at this point in the history
… file
  • Loading branch information
andrewphelpsj committed Jun 26, 2024
1 parent e5a3668 commit 88890b7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 3 deletions.
84 changes: 84 additions & 0 deletions overlord/snapstate/snapstate_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6874,3 +6874,87 @@ func printTasks(ts []*state.Task) string {
}
return b.String()
}

func (s *snapmgrTestSuite) TestInstallComponentsFromPathInvalidComponentFile(c *C) {
s.state.Lock()
defer s.state.Unlock()

// use the real thing for this one
snapstate.MockOpenSnapFile(backend.OpenSnapFile)

const (
snapID = "test-snap-id"
snapName = "test-snap"
componentName = "test-component"
)
snapRevision := snap.R(11)

csi := snap.ComponentSideInfo{
Component: naming.NewComponentRef(snapName, componentName),
Revision: snap.R(1),
}

compPath := filepath.Join(c.MkDir(), "invalid-component")
err := os.WriteFile(compPath, []byte("invalid-component"), 0644)
c.Assert(err, IsNil)

components := map[*snap.ComponentSideInfo]string{
&csi: compPath,
}

snapPath := makeTestSnap(c, `name: test-snap
version: 1.0
components:
test-component:
type: test
`)
si := &snap.SideInfo{
RealName: snapName,
SnapID: snapID,
Revision: snapRevision,
}

goal := snapstate.PathInstallGoal(snapName, snapPath, si, components, snapstate.RevisionOptions{})
_, _, err = snapstate.InstallOne(context.Background(), s.state, goal, snapstate.Options{})
c.Assert(err, ErrorMatches, fmt.Sprintf(`.*cannot process snap or snapdir: file "%s" is invalid.*`, compPath))
}

func (s *snapmgrTestSuite) TestInstallComponentsFromPathInvalidComponentName(c *C) {
s.state.Lock()
defer s.state.Unlock()

// use the real thing for this one
snapstate.MockOpenSnapFile(backend.OpenSnapFile)

const (
snapID = "test-snap-id"
snapName = "test-snap"
componentName = "Bad-component"
)
snapRevision := snap.R(11)

csi := snap.ComponentSideInfo{
Component: naming.NewComponentRef(snapName, componentName),
Revision: snap.R(1),
}

components := map[*snap.ComponentSideInfo]string{
&csi: "",
}

snapPath := makeTestSnap(c, `name: test-snap
version: 1.0
components:
test-component:
type: test
`)
si := &snap.SideInfo{
RealName: snapName,
SnapID: snapID,
Revision: snapRevision,
}

goal := snapstate.PathInstallGoal(snapName, snapPath, si, components, snapstate.RevisionOptions{})
_, _, err := snapstate.InstallOne(context.Background(), s.state, goal, snapstate.Options{})
c.Assert(err, ErrorMatches, fmt.Sprintf(`invalid snap name: "%s"`, componentName))
}
21 changes: 18 additions & 3 deletions overlord/snapstate/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/snapcore/snapd/asserts/snapasserts"
"github.com/snapcore/snapd/client"
"github.com/snapcore/snapd/logger"
"github.com/snapcore/snapd/overlord/snapstate/backend"
"github.com/snapcore/snapd/overlord/state"
"github.com/snapcore/snapd/snap"
Expand Down Expand Up @@ -682,7 +683,7 @@ func (p *pathInstallGoal) toInstall(ctx context.Context, st *state.State, opts O
return nil, err
}

comps, err := installableComponentsFromPaths(info, p.components)
comps, err := componentSetupsFromPaths(info, p.components)
if err != nil {
return nil, err
}
Expand All @@ -701,10 +702,10 @@ func (p *pathInstallGoal) toInstall(ctx context.Context, st *state.State, opts O
return []target{inst}, nil
}

func installableComponentsFromPaths(info *snap.Info, components map[*snap.ComponentSideInfo]string) ([]ComponentSetup, error) {
func componentSetupsFromPaths(snapInfo *snap.Info, components map[*snap.ComponentSideInfo]string) ([]ComponentSetup, error) {
setups := make([]ComponentSetup, 0, len(components))
for csi, path := range components {
compInfo, _, err := backend.OpenComponentFile(path, info, csi)
compInfo, err := validatedComponentInfo(path, csi, snapInfo)
if err != nil {
return nil, err
}
Expand All @@ -718,3 +719,17 @@ func installableComponentsFromPaths(info *snap.Info, components map[*snap.Compon

return setups, nil
}

func validatedComponentInfo(path string, csi *snap.ComponentSideInfo, si *snap.Info) (*snap.ComponentInfo, error) {
if err := csi.Component.Validate(); err != nil {
return nil, err
}
componentInfo, cont, err := backend.OpenComponentFile(path, si, csi)
if err != nil {
return nil, fmt.Errorf("cannot open snap file: %v", err)
}
if err := snap.ValidateComponentContainer(cont, csi.Component.String(), logger.Noticef); err != nil {
return nil, err
}
return componentInfo, nil
}

0 comments on commit 88890b7

Please sign in to comment.