| skipped 116 lines |
117 | 117 | | for _, property := range component.Properties { |
118 | 118 | | c, err := cpe.New(property.Value) |
119 | 119 | | if err != nil { |
120 | | - | log.Debugf("native-image cataloger: could not parse CPE: %v.", err) |
| 120 | + | log.Debugf("unable to parse CPE: %v", err) |
121 | 121 | | continue |
122 | 122 | | } |
123 | 123 | | cpes = append(cpes, c) |
| skipped 32 lines |
156 | 156 | | return nil, fmt.Errorf("could not read from binary file: %w", err) |
157 | 157 | | } |
158 | 158 | | |
159 | | - | log.WithFields("len", storedLength).Trace("native-image cataloger: found SBOM") |
| 159 | + | log.WithFields("len", storedLength).Trace("found java native-image SBOM") |
160 | 160 | | sbomEnd := sbomStart + storedLength |
161 | 161 | | if sbomEnd > uint64(bufLen) { |
162 | 162 | | return nil, errors.New("the sbom symbol overflows the binary") |
| skipped 3 lines |
166 | 166 | | p = bytes.NewBuffer(sbomCompressed) |
167 | 167 | | gzreader, err := gzip.NewReader(p) |
168 | 168 | | if err != nil { |
169 | | - | return nil, fmt.Errorf("could not decompress the native-image SBOM: %w", err) |
| 169 | + | return nil, fmt.Errorf("could not decompress the java native-image SBOM: %w", err) |
170 | 170 | | } |
171 | 171 | | |
172 | 172 | | output, err := io.ReadAll(gzreader) |
173 | 173 | | if err != nil { |
174 | | - | return nil, fmt.Errorf("could not read the native-image SBOM: %w", err) |
| 174 | + | return nil, fmt.Errorf("could not read the java native-image SBOM: %w", err) |
175 | 175 | | } |
176 | 176 | | |
177 | 177 | | var sbomContent nativeImageCycloneDX |
178 | 178 | | err = json.Unmarshal(output, &sbomContent) |
179 | 179 | | if err != nil { |
180 | | - | return nil, fmt.Errorf("could not unmarshal the native-image SBOM: %w", err) |
| 180 | + | return nil, fmt.Errorf("could not unmarshal the java native-image SBOM: %w", err) |
181 | 181 | | } |
182 | 182 | | |
183 | 183 | | for _, component := range sbomContent.Components { |
| skipped 15 lines |
199 | 199 | | // First attempt to read an ELF file. |
200 | 200 | | bi, err := elf.NewFile(r) |
201 | 201 | | |
202 | | - | // The reader does not refer to an ELF file. |
203 | 202 | | if err != nil { |
| 203 | + | var fmtErr *elf.FormatError |
| 204 | + | if errors.As(err, &fmtErr) { |
| 205 | + | // this is not an elf file |
| 206 | + | log.WithFields("filename", filename, "error", err).Trace("not an ELF binary") |
| 207 | + | return nil, nil |
| 208 | + | } |
204 | 209 | | return fileError(filename, err) |
205 | 210 | | } |
| 211 | + | if bi == nil { |
| 212 | + | return nil, nil |
| 213 | + | } |
206 | 214 | | return nativeImageElf{ |
207 | 215 | | file: bi, |
208 | 216 | | }, nil |
| skipped 4 lines |
213 | 221 | | // First attempt to read an ELF file. |
214 | 222 | | bi, err := macho.NewFile(r) |
215 | 223 | | |
216 | | - | // The reader does not refer to an MachO file. |
217 | 224 | | if err != nil { |
218 | | - | return fileError(filename, err) |
| 225 | + | var fmtErr *macho.FormatError |
| 226 | + | if errors.As(err, &fmtErr) { |
| 227 | + | // this is not a MachO file |
| 228 | + | log.WithFields("filename", filename, "error", err).Trace("not a MachO binary") |
| 229 | + | return nil, nil |
| 230 | + | } |
| 231 | + | } |
| 232 | + | if bi == nil { |
| 233 | + | return nil, nil |
219 | 234 | | } |
220 | 235 | | return nativeImageMachO{ |
221 | 236 | | file: bi, |
| skipped 2 lines |
224 | 239 | | |
225 | 240 | | // newPE reads a Native Image from a Portable Executable file. |
226 | 241 | | func newPE(filename string, r io.ReaderAt) (nativeImage, error) { |
227 | | - | // First attempt to read an ELF file. |
| 242 | + | // First attempt to read an PE file. |
228 | 243 | | bi, err := pe.NewFile(r) |
229 | 244 | | |
230 | | - | // The reader does not refer to an MachO file. |
| 245 | + | // The reader does not refer to a PE file. |
231 | 246 | | if err != nil { |
232 | | - | return fileError(filename, err) |
| 247 | + | // note: there isn't a good way to distinguish between a format error and other kinds of errors |
| 248 | + | log.WithFields("filename", filename, "error", err).Trace("not a PE binary") |
| 249 | + | return nil, nil |
| 250 | + | } |
| 251 | + | if bi == nil { |
| 252 | + | return nil, nil |
233 | 253 | | } |
| 254 | + | |
234 | 255 | | var exportSymbolsDataDirectory pe.DataDirectory |
235 | 256 | | switch h := bi.OptionalHeader.(type) { |
236 | 257 | | case *pe.OptionalHeader32: |
| skipped 45 lines |
282 | 303 | | }() |
283 | 304 | | |
284 | 305 | | bi := ni.file |
285 | | - | if bi == nil { |
286 | | - | log.Debugf("native-image cataloger: file is nil") |
287 | | - | return nil, nil |
288 | | - | } |
289 | 306 | | var sbom elf.Symbol |
290 | 307 | | var sbomLength elf.Symbol |
291 | 308 | | var svmVersion elf.Symbol |
| skipped 48 lines |
340 | 357 | | var svmVersion macho.Symbol |
341 | 358 | | |
342 | 359 | | bi := ni.file |
343 | | - | if bi == nil { |
344 | | - | log.Debugf("native-image cataloger: file is nil") |
345 | | - | return nil, nil |
346 | | - | } |
347 | 360 | | if bi.Symtab == nil { |
348 | 361 | | return nil, errors.New(nativeImageMissingSymbolsError) |
349 | 362 | | } |
| skipped 17 lines |
367 | 380 | | } |
368 | 381 | | dataBuf, err := dataSegment.Data() |
369 | 382 | | if err != nil { |
370 | | - | log.Debugf("native-image cataloger: cannot obtain buffer from data segment.") |
| 383 | + | log.Tracef("cannot obtain buffer from data segment") |
371 | 384 | | return nil, nil |
372 | 385 | | } |
373 | 386 | | sbomLocation := sbom.Value - dataSegment.Addr |
| skipped 8 lines |
382 | 395 | | n := len(ni.exports) |
383 | 396 | | j := int(unsafe.Sizeof(ni.header)) + i*int(unsafe.Sizeof(ni.t.headerAttribute)) |
384 | 397 | | if j+4 >= n { |
385 | | - | log.Debugf("native-image cataloger: invalid index to export directory entry attribute: %v.", j) |
| 398 | + | log.Tracef("invalid index to export directory entry attribute: %v", j) |
386 | 399 | | return uint32(0), errors.New(nativeImageInvalidIndexError) |
387 | 400 | | } |
388 | 401 | | p := bytes.NewBuffer(ni.exports[j : j+4]) |
389 | 402 | | err := binary.Read(p, binary.LittleEndian, &attribute) |
390 | 403 | | if err != nil { |
391 | | - | log.Debugf("native-image cataloger: error fetching export directory entry attribute: %v.", err) |
| 404 | + | log.Tracef("error fetching export directory entry attribute: %v", err) |
392 | 405 | | return uint32(0), err |
393 | 406 | | } |
394 | 407 | | return attribute, nil |
| skipped 7 lines |
402 | 415 | | sz := uint32(unsafe.Sizeof(ni.t.functionPointer)) |
403 | 416 | | j := functionsBase + i*sz |
404 | 417 | | if j+sz >= n { |
405 | | - | log.Debugf("native-image cataloger: invalid index to exported function: %v.", j) |
| 418 | + | log.Tracef("invalid index to exported function: %v", j) |
406 | 419 | | return uint32(0), errors.New(nativeImageInvalidIndexError) |
407 | 420 | | } |
408 | 421 | | p := bytes.NewBuffer(ni.exports[j : j+sz]) |
409 | 422 | | err := binary.Read(p, binary.LittleEndian, &pointer) |
410 | 423 | | if err != nil { |
411 | | - | log.Debugf("native-image cataloger: error fetching exported function: %v.", err) |
| 424 | + | log.Tracef("error fetching exported function: %v", err) |
412 | 425 | | return uint32(0), err |
413 | 426 | | } |
414 | 427 | | return pointer, nil |
| skipped 37 lines |
452 | 465 | | k := addressBase + j |
453 | 466 | | sz := uint32(unsafe.Sizeof(ni.t.namePointer)) |
454 | 467 | | if k+sz >= n { |
455 | | - | log.Debugf("native-image cataloger: invalid index to exported function: %v.", k) |
| 468 | + | log.Tracef("invalid index to exported function: %v", k) |
456 | 469 | | // If we are at the end of exports, stop looking |
457 | 470 | | return |
458 | 471 | | } |
| skipped 1 lines |
460 | 473 | | p := bytes.NewBuffer(ni.exports[k : k+sz]) |
461 | 474 | | err := binary.Read(p, binary.LittleEndian, &symbolAddress) |
462 | 475 | | if err != nil { |
463 | | - | log.Debugf("native-image cataloger: error fetching address of symbol %v.", err) |
| 476 | + | log.Tracef("error fetching address of symbol %v", err) |
464 | 477 | | return |
465 | 478 | | } |
466 | 479 | | symbolBase := symbolAddress - ni.exportSymbols.VirtualAddress |
467 | 480 | | if symbolBase >= n { |
468 | | - | log.Debugf("native-image cataloger: invalid index to exported symbol: %v.", symbolBase) |
| 481 | + | log.Tracef("invalid index to exported symbol: %v", symbolBase) |
469 | 482 | | return |
470 | 483 | | } |
471 | 484 | | switch { |
| skipped 19 lines |
491 | 504 | | |
492 | 505 | | content, err := ni.fetchExportContent() |
493 | 506 | | if err != nil { |
494 | | - | log.Debugf("native-image cataloger: could not fetch the content of the export directory entry: %v.", err) |
| 507 | + | log.Debugf("could not fetch the content of the export directory entry: %v", err) |
495 | 508 | | return nil, err |
496 | 509 | | } |
497 | 510 | | ni.fetchSbomSymbols(content) |
| skipped 18 lines |
516 | 529 | | } |
517 | 530 | | dataBuf, err := dataSection.Data() |
518 | 531 | | if err != nil { |
519 | | - | log.Debugf("native-image cataloger: cannot obtain buffer from .data section.") |
| 532 | + | log.Tracef("cannot obtain buffer from the java native-image .data section") |
520 | 533 | | return nil, nil |
521 | 534 | | } |
522 | 535 | | sbomLocation := sbomAddress - dataSection.VirtualAddress |
| skipped 5 lines |
528 | 541 | | // fetchPkgs provides the packages available in a UnionReader. |
529 | 542 | | func fetchPkgs(reader unionreader.UnionReader, filename string) []pkg.Package { |
530 | 543 | | var pkgs []pkg.Package |
531 | | - | imageformats := []func(string, io.ReaderAt) (nativeImage, error){newElf, newMachO, newPE} |
| 544 | + | imageFormats := []func(string, io.ReaderAt) (nativeImage, error){newElf, newMachO, newPE} |
532 | 545 | | |
533 | 546 | | // NOTE: multiple readers are returned to cover universal binaries, which are files |
534 | 547 | | // with more than one binary |
535 | 548 | | readers, err := unionreader.GetReaders(reader) |
536 | 549 | | if err != nil { |
537 | | - | log.Debugf("native-image cataloger: failed to open a binary: %v.", err) |
| 550 | + | log.Debugf("failed to open the java native-image binary: %v", err) |
538 | 551 | | return nil |
539 | 552 | | } |
540 | 553 | | for _, r := range readers { |
541 | | - | for _, makeNativeImage := range imageformats { |
| 554 | + | for _, makeNativeImage := range imageFormats { |
542 | 555 | | ni, err := makeNativeImage(filename, r) |
543 | 556 | | if err != nil { |
544 | 557 | | continue |
545 | 558 | | } |
546 | | - | newpkgs, err := ni.fetchPkgs() |
| 559 | + | if ni == nil { |
| 560 | + | continue |
| 561 | + | } |
| 562 | + | newPkgs, err := ni.fetchPkgs() |
547 | 563 | | if err != nil { |
548 | | - | log.Debugf("native-image cataloger: error extracting SBOM from %s: %v.", filename, err) |
| 564 | + | log.Tracef("unable to extract SBOM from possible java native-image %s: %v", filename, err) |
549 | 565 | | continue |
550 | 566 | | } |
551 | | - | pkgs = append(pkgs, newpkgs...) |
| 567 | + | pkgs = append(pkgs, newPkgs...) |
552 | 568 | | } |
553 | 569 | | } |
554 | 570 | | return pkgs |
| skipped 10 lines |
565 | 581 | | for _, location := range fileMatches { |
566 | 582 | | readerCloser, err := resolver.FileContentsByLocation(location) |
567 | 583 | | if err != nil { |
568 | | - | log.Debugf("native-image cataloger: error opening file: %v.", err) |
| 584 | + | log.Debugf("error opening file: %v", err) |
569 | 585 | | continue |
570 | 586 | | } |
571 | | - | log.Tracef("native-image cataloger: found an executable file %v.", location) |
| 587 | + | |
572 | 588 | | reader, err := unionreader.GetUnionReader(readerCloser) |
573 | 589 | | if err != nil { |
574 | 590 | | return nil, nil, err |
575 | 591 | | } |
576 | | - | newpkgs := fetchPkgs(reader, location.RealPath) |
577 | | - | pkgs = append(pkgs, newpkgs...) |
| 592 | + | newPkgs := fetchPkgs(reader, location.RealPath) |
| 593 | + | pkgs = append(pkgs, newPkgs...) |
578 | 594 | | internal.CloseAndLogError(readerCloser, location.RealPath) |
579 | 595 | | } |
580 | 596 | | |
| skipped 3 lines |