github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/kernel/parse_linux_kernel_file.go (about) 1 package kernel 2 3 import ( 4 "context" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/deitch/magic/pkg/magic" 10 11 "github.com/anchore/syft/internal/log" 12 "github.com/anchore/syft/syft/artifact" 13 "github.com/anchore/syft/syft/file" 14 "github.com/anchore/syft/syft/internal/unionreader" 15 "github.com/anchore/syft/syft/pkg" 16 "github.com/anchore/syft/syft/pkg/cataloger/generic" 17 ) 18 19 const linuxKernelMagicName = "Linux kernel" 20 21 func parseLinuxKernelFile(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 22 unionReader, err := unionreader.GetUnionReader(reader) 23 if err != nil { 24 return nil, nil, fmt.Errorf("unable to get union reader for file: %w", err) 25 } 26 magicType, err := magic.GetType(unionReader) 27 if err != nil { 28 return nil, nil, fmt.Errorf("unable to get magic type for file: %w", err) 29 } 30 if len(magicType) < 1 || magicType[0] != linuxKernelMagicName { 31 return nil, nil, nil 32 } 33 metadata := parseLinuxKernelMetadata(magicType) 34 if metadata.Version == "" { 35 return nil, nil, nil 36 } 37 38 return []pkg.Package{ 39 newLinuxKernelPackage( 40 metadata, 41 reader.Location, 42 ), 43 }, nil, nil 44 } 45 46 func parseLinuxKernelMetadata(magicType []string) (p pkg.LinuxKernel) { 47 // Linux kernel x86 boot executable bzImage, 48 // version 5.10.121-linuxkit (root@buildkitsandbox) #1 SMP Fri Dec 2 10:35:42 UTC 2022, 49 // RO-rootFS, 50 // swap_dev 0XA, 51 // Normal VGA 52 for _, t := range magicType { 53 switch { 54 case strings.HasPrefix(t, "x86 "): 55 p.Architecture = "x86" 56 case strings.Contains(t, "ARM64 "): 57 p.Architecture = "arm64" 58 case strings.Contains(t, "ARM "): 59 p.Architecture = "arm" 60 case t == "bzImage": 61 p.Format = "bzImage" 62 case t == "zImage": 63 p.Format = "zImage" 64 case strings.HasPrefix(t, "version "): 65 p.ExtendedVersion = strings.TrimPrefix(t, "version ") 66 fields := strings.Fields(p.ExtendedVersion) 67 if len(fields) > 0 { 68 p.Version = fields[0] 69 } 70 case strings.Contains(t, "rootFS") && strings.HasPrefix(t, "RW-"): 71 p.RWRootFS = true 72 case strings.HasPrefix(t, "swap_dev "): 73 swapDevStr := strings.TrimPrefix(t, "swap_dev ") 74 swapDev, err := strconv.ParseInt(swapDevStr, 16, 32) 75 if err != nil { 76 log.Warnf("unable to parse swap device: %s", err) 77 continue 78 } 79 p.SwapDevice = int(swapDev) 80 case strings.HasPrefix(t, "root_dev "): 81 rootDevStr := strings.TrimPrefix(t, "root_dev ") 82 rootDev, err := strconv.ParseInt(rootDevStr, 16, 32) 83 if err != nil { 84 log.Warnf("unable to parse root device: %s", err) 85 continue 86 } 87 p.SwapDevice = int(rootDev) 88 case strings.Contains(t, "VGA") || strings.Contains(t, "Video"): 89 p.VideoMode = t 90 } 91 } 92 return p 93 }