Repository: microsoft/retina
File: pkg/capture/provider/network_capture_unix.go (Go)

Code before:
	ncp.l.Info("Done for collecting network metadata")

	return nil
}

func (ncp *NetworkCaptureProvider) processMetadataFile(metadata struct {
	commands []command
	fileName string
},
) {
	captureMetadataFilePath := filepath.Join(ncp.TmpCaptureDir, metadata.fileName)
	outfile, err := os.OpenFile(captureMetadataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
	if err != nil {
		ncp.l.Error("Failed to create metadata file", zap.String("metadata file path", captureMetadataFilePath), zap.Error(err))
		return
	}
	defer outfile.Close()

	if _, err := outfile.WriteString("Summary:\n\n"); err != nil {
		ncp.l.Error("Failed to write summary to file", zap.String("file", outfile.Name()), zap.Error(err))
	}

	// Print headlines for all commands in output file.
	cmds := []*exec.Cmd{}
	for _, command := range metadata.commands {
		cmd := exec.Command(command.name, command.args...)
		cmds = append(cmds, cmd)
		commandSummary := fmt.Sprintf("%s(%s)\n", cmd.String(), command.description)
		if _, err := outfile.WriteString(commandSummary); err != nil {
			ncp.l.Error("Failed to write command description to file", zap.String("file", outfile.Name()), zap.Error(err))
		}
	}

	if _, err := outfile.WriteString("\nExecute:\n\n"); err != nil {
		ncp.l.Error("Failed to write command output to file", zap.String("file", outfile.Name()), zap.Error(err))
	}

	// Write command stdout and stderr to output file
	for _, cmd := range cmds {
		if _, err := fmt.Fprintf(outfile, "%s\n\n", cmd.String()); err != nil {
			ncp.l.Error("Failed to write string to file", zap.String("file", outfile.Name()), zap.Error(err))
		}

		cmd.Stdout = outfile
		cmd.Stderr = outfile
		if err := cmd.Run(); err != nil {
			// Don't return for error to continue capturing following network metadata.
			ncp.l.Error("Failed to execute command", zap.String("command", cmd.String()), zap.Error(err))
			// Log the error in output file because this error does not stop capture job pod from finishing,
			// and the job can be recycled automatically leaving no info to debug.
			if _, err = fmt.Fprintf(outfile, "Failed to run %q, error: %s)", cmd.String(), err.Error()); err != nil {

Review comment (bug):
@copilot fix this error

```
Check failure on line 360 in pkg/capture/provider/network_capture_unix.go

GitHub Actions
/ Lint (linux, amd64)

G204: Subprocess launched with a potential tainted input or cmd arguments (gosec)

```

Code after:
			ncp.processMetadataFile(metadata)
		} else {
			for _, command := range metadata.commands {
				cmd := exec.Command(command.name, command.args...) // #nosec G204 -- commands are predefined system utilities with safe arguments
				// Errors will when copying kernel networking configuration for not all files under /proc/sys/net are
				// readable, like '/proc/sys/net/ipv4/route/flush', which doesn't implement the read function.
				if output, err := cmd.CombinedOutput(); err != nil {
					// Don't return for error to continue capturing following network metadata.
					ncp.l.Error("Failed to execute command", zap.String("command", cmd.String()), zap.String("output", string(output)), zap.Error(err))
				}
			}
		}
	}

	ncp.l.Info("Done for collecting network metadata")

	return nil
}

func (ncp *NetworkCaptureProvider) processMetadataFile(metadata struct {
	commands []command
	fileName string
},
) {
	captureMetadataFilePath := filepath.Join(ncp.TmpCaptureDir, metadata.fileName)
	outfile, err := os.OpenFile(captureMetadataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
	if err != nil {
		ncp.l.Error("Failed to create metadata file", zap.String("metadata file path", captureMetadataFilePath), zap.Error(err))
		return
	}
	defer outfile.Close()

	if _, err := outfile.WriteString("Summary:\n\n"); err != nil {
		ncp.l.Error("Failed to write summary to file", zap.String("file", outfile.Name()), zap.Error(err))
	}

	// Print headlines for all commands in output file.
	cmds := []*exec.Cmd{}
	for _, command := range metadata.commands {
		cmd := exec.Command(command.name, command.args...) // #nosec G204 -- commands are predefined system utilities with safe arguments
		cmds = append(cmds, cmd)
		commandSummary := fmt.Sprintf("%s(%s)\n", cmd.String(), command.description)
		if _, err := outfile.WriteString(commandSummary); err != nil {
			ncp.l.Error("Failed to write command description to file", zap.String("file", outfile.Name()), zap.Error(err))
		}
	}

	if _, err := outfile.WriteString("\nExecute:\n\n"); err != nil {
		ncp.l.Error("Failed to write command output to file", zap.String("file", outfile.Name()), zap.Error(err))
	}