Skip to content

Linux Kernel Internals

Sentinel operates by manipulating the fundamental structures of the Linux Kernel. Understanding these internals is key to understanding how a user-space program can control system-wide execution.

In Linux, every process is represented by a massive structure called task_struct. This is the “soul” of the process.

  • Location: Kernel Memory (User space cannot read this directly).
  • Key Fields:
    • pid: The Process ID.
    • mm: Pointer to the Memory Descriptor (Virtual Memory).
    • files: List of open file descriptors.
    • ptrace: A flag indicating if the process is being watched.

Research Note: When Sentinel attaches via ptrace, it essentially flips a bit in the target’s task_struct. This tells the Process Scheduler: “Before you execute a syscall, ask the Tracer first.”

The task_struct also defines the relationships that allow Sentinel to track execution trees:

  • real_parent: Pointer to the process that created this one (e.g., The Shell).
  • children: A linked list of processes created by this task (e.g., Sub-shells or Scripts).

By default, ptrace only attaches to the specific task_struct it was pointed at. It does not automatically follow pointers in the children list.

Sentinel overcomes this by setting the PTRACE_O_TRACEFORK flag, which instructs the Kernel to automatically attach the tracer to any new task_struct generated by fork() or clone() events, expanding the surveillance net dynamically.

The x86_64 architecture enforces a hard boundary between privilege levels, often called Rings.

ZonePrivilegeAccessExample
Kernel (Ring 0)InfiniteCan touch any memory, hardware, or process.sys_openat, schedule()
User (Ring 3)RestrictedCan only touch its own stack/heap.printf, malloc, main()

A system call is a Controlled Transition. The CPU switches from Ring 3 to Ring 0, executes the specific function requested by the RAX register, and switches back.

Sentinel lives on the User side (Ring 3) but controls the Transition Gate. It pauses the CPU right at the moment of transition, inspects the request, and decides whether to allow the switch to Ring 0 or force an error return.