Skip to content

Commit

Permalink
Guard against os-release panic (#1488)
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Johnson <[email protected]>
  • Loading branch information
jonjohnsonjr authored Jan 22, 2025
1 parent 50e09b6 commit 2221938
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require (
chainguard.dev/sdk v0.1.29
github.com/chainguard-dev/clog v1.5.1
github.com/charmbracelet/log v0.4.0
github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f
github.com/go-git/go-git/v5 v5.13.1
github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.20.3
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f h1:oEt43goQgsL1DzoOyQ/UZHQw7t9TqwyJec9W0vh0wfE=
github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f/go.mod h1:RU3x9VqPvzbOGJ3wtP0pPBtUOp4yU/yzA/8qdxgi/6Q=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
Expand Down
47 changes: 40 additions & 7 deletions pkg/build/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
package build

import (
"bufio"
"context"
"errors"
"fmt"
"io"
"io/fs"
"log/slog"
"path/filepath"
"sort"
"strings"
"time"

osr "github.com/dominodatalab/os-release"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
ggcrtypes "github.com/google/go-containerregistry/pkg/v1/types"
Expand Down Expand Up @@ -151,13 +151,20 @@ func (bc *Context) GenerateImageSBOM(ctx context.Context, arch types.Architectur
return sboms, nil
}

type ReleaseData struct {
ID string
Name string
PrettyName string
VersionID string
}

// readReleaseData reads the information from /etc/os-release
//
// If no os-release file is found, it returns a Data struct with ID set to "unknown".
func readReleaseData(fsys fs.FS) (*osr.Data, error) {
func readReleaseData(fsys fs.FS) (*ReleaseData, error) {
f, err := fsys.Open("/etc/os-release")
if errors.Is(err, fs.ErrNotExist) {
return &osr.Data{
return &ReleaseData{
ID: "unknown",
Name: "apko-generated image",
VersionID: "unknown",
Expand All @@ -166,12 +173,38 @@ func readReleaseData(fsys fs.FS) (*osr.Data, error) {
return nil, fmt.Errorf("opening os-release: %w", err)
}
defer f.Close()
osReleaseData, err := io.ReadAll(f)
if err != nil {

scanner := bufio.NewScanner(f)

kv := map[string]string{}
for scanner.Scan() {
line := scanner.Text()
if line == "" {
continue
}

if strings.HasPrefix(line, "#") {
continue
}

before, after, ok := strings.Cut(line, "=")
if !ok {
return nil, fmt.Errorf("invalid os-release line: %q", line)
}

kv[before] = strings.Trim(after, "\"")
}

if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("reading os-release: %w", err)
}

return osr.Parse(string(osReleaseData)), nil
return &ReleaseData{
ID: kv["ID"],
Name: kv["NAME"],
PrettyName: kv["PRETTY_NAME"],
VersionID: kv["VERSION_ID"],
}, nil
}

func GenerateIndexSBOM(ctx context.Context, o options.Options, ic types.ImageConfiguration, indexDigest name.Digest, imgs map[types.Architecture]oci.SignedImage) ([]types.SBOM, error) {
Expand Down
14 changes: 13 additions & 1 deletion pkg/build/sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import (
)

func TestReadReleaseData(t *testing.T) {
osinfoData := `ID=wolfi
osinfoData := `# This is a comment that should be ignored.
ID=wolfi
NAME="Wolfi"
PRETTY_NAME="Wolfi"
VERSION_ID="2022, 20230914"
Expand All @@ -52,3 +53,14 @@ func TestReadReleaseData_EmptyDefaults(t *testing.T) {
require.Equal(t, "unknown", info.VersionID)
require.Equal(t, "", info.PrettyName)
}

func TestBadReleaseData(t *testing.T) {
osinfoData := `hello, world! this is not a valid os-release file
`
fsys := apkfs.NewMemFS()
require.NoError(t, fsys.MkdirAll(filepath.Dir("/etc/os-release"), os.FileMode(0o644)))
require.NoError(t, fsys.WriteFile("/etc/os-release", []byte(osinfoData), os.FileMode(0o644)))
// Bad data in file should err.
_, err := readReleaseData(fsys)
require.Error(t, err)
}

0 comments on commit 2221938

Please sign in to comment.