validateOpenFDs checks that the sandbox process does not have any open directory FDs.
(passFDs []boot.FDMapping)
| 698 | // validateOpenFDs checks that the sandbox process does not have any open |
| 699 | // directory FDs. |
| 700 | func validateOpenFDs(passFDs []boot.FDMapping) { |
| 701 | passHostFDs := make(map[int]struct{}) |
| 702 | for _, passFD := range passFDs { |
| 703 | passHostFDs[passFD.Host] = struct{}{} |
| 704 | } |
| 705 | const selfFDDir = "/proc/self/fd" |
| 706 | if err := filepath.WalkDir(selfFDDir, func(path string, d os.DirEntry, err error) error { |
| 707 | if err != nil { |
| 708 | return err |
| 709 | } |
| 710 | if d.Type() != os.ModeSymlink { |
| 711 | // All entries are symlinks. Ignore the callback for fd directory itself. |
| 712 | return nil |
| 713 | } |
| 714 | if fdInfo, err := os.Stat(path); err != nil { |
| 715 | if os.IsNotExist(err) { |
| 716 | // Ignore FDs that are now closed. For example, the FD to selfFDDir that |
| 717 | // was opened by filepath.WalkDir() to read dirents. |
| 718 | return nil |
| 719 | } |
| 720 | return fmt.Errorf("os.Stat(%s) failed: %v", path, err) |
| 721 | } else if !fdInfo.IsDir() { |
| 722 | return nil |
| 723 | } |
| 724 | // Uh-oh. This is a directory FD. |
| 725 | fdNo, err := strconv.Atoi(d.Name()) |
| 726 | if err != nil { |
| 727 | return fmt.Errorf("strconv.Atoi(%s) failed: %v", d.Name(), err) |
| 728 | } |
| 729 | dirLink, err := os.Readlink(path) |
| 730 | if err != nil { |
| 731 | return fmt.Errorf("os.Readlink(%s) failed: %v", path, err) |
| 732 | } |
| 733 | if _, ok := passHostFDs[fdNo]; ok { |
| 734 | // Passed FDs are allowed to be directories. The user must be knowing |
| 735 | // what they are doing. Log a warning regardless. |
| 736 | log.Warningf("Sandbox has access to FD %d, which is a directory for %s", fdNo, dirLink) |
| 737 | return nil |
| 738 | } |
| 739 | return fmt.Errorf("FD %d is a directory for %s", fdNo, dirLink) |
| 740 | }); err != nil { |
| 741 | util.Fatalf("WalkDir(%s) failed: %v", selfFDDir, err) |
| 742 | } |
| 743 | } |
| 744 | |
| 745 | // exportFinalMetrics exports all metrics to the given file. |
| 746 | // The file is closed as part of this function. |
no test coverage detected
searching dependent graphs…