Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/cli/home_local_fallback.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -110,7 +110,7 @@ func tbAliasAvailable() bool {
// different tracebloc at another path (Bugbot). Case-insensitive: .cmd is a
// Windows artifact and NTFS paths are case-insensitive.
func tbCmdAliasOurs(dir, exe string) bool {
b, err := os.ReadFile(filepath.Join(dir, binTB+".cmd"))
b, err := os.ReadFile(filepath.Join(dir, binTB+".cmd")) // #nosec G304 -- fixed name next to os.Executable(): inspects the install dir's own tb.cmd shim; whoever controls that dir already controls the binary.
if err != nil {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/ingest.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -75,7 +75,7 @@ Exit codes:
func runIngestValidate(cmd *cobra.Command, args []string) error {
path := args[0]

body, err := os.ReadFile(path)
body, err := os.ReadFile(path) // #nosec G304 -- reading the ingest.yaml the operator named as the positional arg is this command's documented job; local CLI, invoking user's privileges.
if err != nil {
// fileError is exit-code 3 territory. We use a sentinel
// exit-coded error so cobra propagates the right code via
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/installlog.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,7 +34,7 @@ func newInstallLog() (*installLog, string) {
return nil, ""
}
path := filepath.Join(dir, "install-"+time.Now().UTC().Format("20060102-150405")+".log")
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) // #nosec G304 -- creates (never reads) the install log at a timestamp-generated name under the CLI's own 0700 config dir, mode 0600.
if err != nil {
// No file was created — return an empty path so the caller never
// advertises a "Full log:" location that doesn't exist (Bugbot).
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/prepare_host.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -110,7 +110,7 @@ func prepareHostEnv(user string) []string {
// that traps signals. We rely on the default SIGKILL rather than a custom
// SIGINT-only Cancel (which a privileged child could ignore, hanging Wait).
func prepareHostCmd(ctx context.Context) *exec.Cmd {
c := exec.CommandContext(ctx, "bash", "-c", prepareHostInstallerCmd)
c := exec.CommandContext(ctx, "bash", "-c", prepareHostInstallerCmd) // #nosec G204 -- argv is compile-time constant: literal "bash" -c installerRunScript("prepare-host"), built only from the installerURL const; no runtime input.
c.WaitDelay = 5 * time.Second
return c
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/update_check.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -164,7 +164,7 @@ func readUpdateCache(path string) (updateCache, bool) {
if path == "" {
return updateCache{}, false
}
raw, err := os.ReadFile(path)
raw, err := os.ReadFile(path) // #nosec G304 -- the CLI's own throttle cache: config.Dir() + the constant updateCacheFile name; contents JSON-validated before use.
if err != nil {
return updateCache{}, false
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/upgrade.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -120,7 +120,7 @@ Safe to run anytime; safe to re-run.`,
// Stream the installer straight to the user's terminal, and keep
// stdin wired so its interactive prompts (sign-in, etc.) still work.
ctx := cmd.Context()
c := exec.CommandContext(ctx, plan.name, plan.args...)
c := exec.CommandContext(ctx, plan.name, plan.args...) // #nosec G204 -- upgradePlanFor(runtime.GOOS) yields compile-time constants: "bash" -c installerRunScript(""); only the GOOS branch varies, no user input.
c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
if err := c.Run(); err != nil {
// User aborted (Ctrl-C) or the parent context was cancelled: exit
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,7 +122,7 @@ func Load() (*Config, error) {
if err != nil {
return nil, err
}
data, err := os.ReadFile(path)
data, err := os.ReadFile(path) // #nosec G304 -- the CLI's own config: Dir()/config.json under ~/.tracebloc or the operator's explicit $TRACEBLOC_CONFIG_DIR override, read as the invoking user.
if errors.Is(err, fs.ErrNotExist) {
return &Config{Version: schemaVersion, Profiles: map[string]*Profile{}}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion internal/helm/upgrade.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,7 +53,7 @@ const (
// var so tests substitute a fake without spawning real helm. Mirrors
// nodeboot.Runner exactly.
var Runner = func(ctx context.Context, name string, args ...string) (string, error) {
out, err := exec.CommandContext(ctx, name, args...).CombinedOutput()
out, err := exec.CommandContext(ctx, name, args...).CombinedOutput() // #nosec G204 -- test seam: every caller passes the literal "helm"; args are the operator's own release/kubeconfig flags, exec'd as an argv array, no shell.
return string(out), err
}

Expand Down
2 changes: 1 addition & 1 deletion internal/nodeboot/nodeboot.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@ const imageReference = "ghcr.io/tracebloc/*"
// Runner executes an external command and returns its combined output. A package
// var so tests can substitute a fake without spawning real k3d/helm/docker.
var Runner = func(ctx context.Context, name string, args ...string) (string, error) {
out, err := exec.CommandContext(ctx, name, args...).CombinedOutput()
out, err := exec.CommandContext(ctx, name, args...).CombinedOutput() // #nosec G204 -- test seam: callers pass literal tool names (k3d/helm/docker) with argv from package consts and the operator's own cluster/release names; no shell.
return string(out), err
}

Expand Down
2 changes: 1 addition & 1 deletion internal/push/detect.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,7 +27,7 @@ import (
// default, advising --target-size. (Since Discover only yields the
// ingestor's accept-set — .jpg/.jpeg/.png — that path is defensive.)
func DetectImageSize(path string) (width, height int, err error) {
f, err := os.Open(path)
f, err := os.Open(path) // #nosec G304 -- decodes the header of an image the symlink-rejecting dataset walk found under the operator-chosen root; operator's own file.
if err != nil {
return 0, 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/push/image_resolution.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,7 +27,7 @@ import (
func scanImageResolutions(paths []string, expectedW, expectedH, minW, minH int) (broken, tooSmall, mismatched []string) {
for _, path := range paths {
name := filepath.Base(path)
f, err := os.Open(path)
f, err := os.Open(path) // #nosec G304 -- paths come from the symlink-rejecting dataset walk of the operator-chosen root; mirrors the in-cluster validator on the operator's own files.
if err != nil {
broken = append(broken, fmt.Sprintf("%s (unreadable: %v)", name, err))
continue
Expand Down
6 changes: 3 additions & 3 deletions internal/push/preflight.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,7 +42,7 @@ var utf8BOM = []byte{0xEF, 0xBB, 0xBF}
// non-EOF Read error is only ever a genuine I/O failure, so callers can treat
// it as fail-closed. The caller closes the returned Closer.
func openCSVReader(path string) (*csv.Reader, io.Closer, error) {
f, err := os.Open(path)
f, err := os.Open(path) // #nosec G304 -- opens the operator's own dataset CSV to mirror the ingestor's checks locally before upload; no privilege boundary crossed.
if err != nil {
return nil, nil, err
}
Expand DownExpand Up@@ -78,7 +78,7 @@ func matchColumnIndex(header []string, want string) int {

// HasBOM reports whether the file starts with a UTF-8 BOM.
func HasBOM(path string) (bool, error) {
f, err := os.Open(path)
f, err := os.Open(path) // #nosec G304 -- 3-byte BOM sniff of the same operator-supplied dataset CSV openCSVReader reads; local preflight as the invoking user.
if err != nil {
return false, err
}
Expand DownExpand Up@@ -802,7 +802,7 @@ func hasKnownExtension(name string) bool {
// the FIRST gate validate_data runs in-cluster: the CSV must be valid UTF-8
// and free of NUL bytes, or the whole run aborts (after the upload).
func CheckCSVEncoding(path string) error {
f, err := os.Open(path)
f, err := os.Open(path) // #nosec G304 -- encoding-check of the operator's own dataset CSV, size-capped by LimitReader; same local-preflight threat model as openCSVReader.
if err != nil {
return fmt.Errorf("reading %s: %w", filepath.Base(path), err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/push/stream.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -469,7 +469,7 @@ func writeTarFile(tw *tar.Writer, src, dst string) (int64, error) {
if err := tw.WriteHeader(hdr); err != nil {
return 0, err
}
f, err := os.Open(src)
f, err := os.Open(src) // #nosec G304 -- src came from the symlink-rejecting walk and the Lstat guard above re-rejects symlinks at stream time; reads the operator's own dataset file.
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/push/tabular.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -388,7 +388,7 @@ type SchemaInference struct {
// redeclares them. The risky cases (empty-in-sample, id-like) are returned
// alongside the schema so the caller can surface them as warnings.
func InferSchema(csvPath string) (*SchemaInference, error) {
f, err := os.Open(csvPath)
f, err := os.Open(csvPath) // #nosec G304 -- csvPath is the dataset CSV DiscoverTabular's symlink-rejecting walk found under the operator-chosen root; local read as the invoking user.
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/push/text.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -162,7 +162,7 @@ func validateTextRecords(csvPath, dirName string, files []string, rf RecordForma
if path == "" {
continue // manifest names a file not on disk — a missing-file check's job, not ours
}
content, err := os.ReadFile(path)
content, err := os.ReadFile(path) // #nosec G304 -- path comes from byBase/byStem, keyed only by files the symlink-vetted walk found in the dataset dir; a manifest entry selects among them, it cannot point elsewhere.
if err != nil {
return fmt.Errorf("reading %s: %w", filepath.Join(dirName, filepath.Base(path)), err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/slug/slug.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -87,7 +87,7 @@ func toASCII(s string) string {
var b strings.Builder
for _, r := range norm.NFKD.String(s) {
if r < 128 {
b.WriteByte(byte(r))
b.WriteByte(byte(r)) // #nosec G115 -- false positive: range-over-string runes are non-negative and the r < 128 guard bounds them, so byte(r) is a lossless ASCII conversion.
}
}
return b.String()
Expand Down
Loading