cybersecurity · intermediate · ~15 min

Run a program without a shell

Why `system()` is dangerous with untrusted input.

Challenge

Run an external program with one argument without going through a shell, so the argument can never inject extra commands.

Task

Implement int safe_run(const char *prog, const char *arg) that runs prog with the single argument arg using fork + execvp and an explicit argv array (no shell), waits for the child, and returns its exit status. No main — the grader calls it.

Input

  • prog: the program to run (e.g. "/bin/echo").
  • arg: the single argument to pass to it.

Output

The child's exit status as an int (0 on a successful run), or -1 on a fork/wait error.

Example

safe_run("/bin/echo", "hi")        ->   0; prints "hi"
safe_run("/bin/echo", "one; two")  ->   0; the "; two" is one literal argument, NOT a second command

Edge cases

  • If execvp fails, the child should _exit(127).

Rules

  • Do not use system() or a shell. Build a NUL-terminated argv array and call execvp.

Input format

A program path prog and a single argument arg.

Output format

The child's exit status as an int (0 on success), or -1 on error.

Constraints

No shell/system(); use fork + execvp with an explicit NUL-terminated argv.

Starter code

#include <unistd.h>
#include <sys/wait.h>

int safe_run(const char *prog, const char *arg) {
    /* TODO */
    return -1;
}

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.