execveat - Linux


Overview

execveat() is a system call that replaces the current running process with a new program. It is similar to the execve() system call, but with additional features that allow it to be used to run programs in a sandboxed environment.

Syntax

#include <sys/syscall.h>

int execveat(int dirfd, const char *pathname, const char *const argv[],
              const char *const envp[], int flags);

| Argument | Description |
|—|—|
| dirfd | File descriptor of the directory in which to search for the executable file. |
| pathname | The null-terminated path to the executable file. |
| argv | An array of null-terminated strings containing the arguments to the program. |
| envp | An array of null-terminated strings containing the environment variables for the program. |
| flags | Flags that modify the behavior of execveat(). See Options/Flags for details. |

Options/Flags

| Flag | Description |
|—|—|
| AT_EMPTY_PATH | If set, the pathname argument is not searched for in the dirfd directory. |
| AT_NO_SEARCH | If set, the pathname argument is not searched for in any directories. |
| AT_SYMLINK_NOFOLLOW | If set, symbolic links are not followed when resolving the pathname argument. |
| AT_EXECFD | If set, the file descriptor specified by the flags argument is used as the standard input for the program. |

Examples

Simple example: Replace the current process with a new program:

#include <sys/syscall.h>
#include <stdio.h>

int main() {
  execveat(-1, "/bin/ls", (char *[]){ "ls", "-l", NULL }, NULL, 0);
  perror("execveat");
  return 1;
}

Advanced example: Run a program in a sandboxed environment:

#include <sys/syscall.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  int dirfd = open("/tmp/sandbox", O_DIRECTORY | O_RDONLY);
  if (dirfd < 0) {
    perror("open");
    return 1;
  }

  execveat(dirfd, "/bin/ls", (char *[]){ "ls", "-l", NULL }, NULL, AT_NO_SEARCH | AT_EMPTY_PATH);
  perror("execveat");
  close(dirfd);
  return 1;
}

Common Issues

  • Permission denied: Ensure that the current process has permission to execute the specified program and that the dirfd argument refers to a directory that the process has permission to access.
  • File not found: Verify that the specified pathname is correct and that the program exists in the specified dirfd directory.
  • Segmentation fault: Ensure that the argv and envp arrays are properly terminated with a null pointer.

Integration

execveat() can be used in conjunction with other Linux commands and tools to perform advanced tasks, such as:

  • Running programs in a sandboxed environment using namespaces and control groups.
  • Creating custom shells that restrict the programs that can be executed.
  • Executing programs from a specific directory or without searching the $PATH environment variable.

Related Commands

  • execve() – Replaces the current running process with a new program.
  • fork() – Creates a new process.
  • clone() – Creates a new process with specified flags.