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