Skip to content

Softnet SUID setup shell-interprets the resolved executable path #1259

Description

@coygeek

Softnet SUID setup shell-interprets the resolved executable path

Target commit: 6ada2b955d5af1724751056753f22a69f9fe00d1

Summary

Softnet.configureSUIDBitIfNeeded() resolves the softnet executable path and then interpolates that path into a sudo sh -c command. Because the path is interpreted by a shell instead of passed as an argv value, shell metacharacters in the resolved path can change the command that gets executed.

This is especially sensitive because the command is part of the SUID setup path for softnet.

Root Cause

Sources/tart/Network/Softnet.swift builds the chown/chmod operation as a shell string:

process = try Process.run(sudoExecutableURL, arguments: [
  "sh",
  "-c",
  "chown root \(softnetExecutablePath) && chmod u+s \(softnetExecutablePath)",
])

At that point softnetExecutablePath is no longer data passed to chown or chmod; it is part of a shell program. Paths containing spaces or shell syntax can therefore be parsed differently from the intended executable path.

Expected Behavior

Tart should treat the resolved softnet path as data. The path should not be interpreted by a shell.

Actual Behavior

Tart constructs a shell command by string interpolation. A focused local regression fixture with a softnet path containing shell control characters proves that the path is parsed as shell syntax instead of as one executable-path argument.

Fix Sketch

Avoid sh -c for this operation. Run the two privileged operations separately and pass the path as a normal argv element:

sudo chown root <softnet-path>
sudo chmod u+s <softnet-path>

If a shell command must remain, both interpolations need robust shell escaping. Passing argv directly is safer because it removes shell parsing from the path entirely.

Verification

I verified the issue with a focused local XCTest fixture that places a fake softnet on PATH under a directory name containing shell control characters, then calls Softnet.configureSUIDBitIfNeeded(). At the target commit, the test fails because the shell parses the path as syntax. No fix was committed or pushed from this report.

Distinctness

This is distinct from parser/validation reports in other areas. It is specifically about shell command construction in the Softnet SUID setup path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions