> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/linux-internals/01.-linux-architecture-overview-x86-x86_64.md).

# 01. Linux Architecture Overview (x86/x86\_64)

> Goal of this file: build the mental model you'll reuse in every other file, what "kernel" vs "userspace" actually means at the CPU level, why that boundary exists, and how the pieces of a Linux system stack on top of it. This matters enormously for exploit dev: almost every kernel exploit is about breaking or abusing this boundary.

***

### 1. The big picture

Linux is a **monolithic kernel** (with loadable modules).

<figure><img src="/files/WH6eyo3rKrI8CZEQ1NgR" alt=""><figcaption></figcaption></figure>

That means most core services, scheduling, memory management, filesystems, networking, device drivers, run as *one privileged program* in a single address space, not as separate isolated servers (contrast: microkernels like seL4/QNX).

<figure><img src="/files/v7Jr4fUKzK60LYXd0rn6" alt=""><figcaption></figcaption></figure>

```
┌─────────────────────────────────────────────────────────────┐
│                         USER SPACE                           │
│                                                               │
│   bash   vim   nginx   python3   /bin/ls   your-exploit      │
│     |      |      |        |          |          |           │
│     └──────┴──────┴────────┴──────────┴──────────┘           │
│                         glibc (libc)                          │
│           (wraps syscalls: open(), read(), fork()...)         │
└───────────────────────────┬───────────────────────────────────┘
                             │  SYSCALL / SYSENTER / INT 0x80
                             │  (the ONLY sanctioned door in)
┌───────────────────────────▼───────────────────────────────────┐
│                        KERNEL SPACE  (Ring 0)                 │
│                                                                │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│  │  Process   │ │  Memory    │ │ Filesystem │ │  Network   │ │
│  │  Scheduler │ │  Manager   │ │ (VFS/ext4) │ │  Stack     │ │
│  └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐                │
│  │  Device    │ │  IPC       │ │  Security  │                │
│  │  Drivers   │ │ (pipes,sem)│ │ (LSM/SELinux)│              │
│  └────────────┘ └────────────┘ └────────────┘                │
└───────────────────────────┬───────────────────────────────────┘
                             │ machine instructions (in/out, MSR, MMIO)
┌───────────────────────────▼───────────────────────────────────┐
│                          HARDWARE                              │
│   CPU (x86_64)   RAM   Disk controllers   NIC   GPU   ...      │
└─────────────────────────────────────────────────────────────┘
```

Everything a normal program does, printing to a screen, reading a file, opening a socket, eventually becomes a **system call** into this kernel blob. The kernel is the only code allowed to talk to hardware directly.

***

### 2. CPU privilege rings

x86/x86\_64 CPUs implement **4 protection rings** in hardware (0–3), baked into the CPU since the 80286. Linux only uses two of them:

```
        Ring 0  ────────────────►  Kernel mode   (full hardware access)
        Ring 1  ────────────────►  unused by Linux
        Ring 2  ────────────────►  unused by Linux
        Ring 3  ────────────────►  User mode     (restricted)
```

* **Ring 0**: can execute *privileged instructions* (e.g. `lgdt`, `lidt`, `hlt`, `mov cr3, rax`, `wrmsr`), access all memory, mask interrupts, talk to I/O ports directly.
* **Ring 3**: cannot execute privileged instructions (CPU raises a `#GP` General Protection fault if you try), memory access is checked against page tables, no direct I/O port access.

<figure><img src="/files/rVPVIBYiqo7xapXhRLJ2" alt=""><figcaption></figcaption></figure>

The CPU tracks the *current privilege level* (CPL) in the low 2 bits of the `CS` (code segment) register. Every memory access is checked against this.

**Why this matters for exploit dev**: a kernel exploit's entire purpose is usually to get *arbitrary code execution while CPL=0*, or to corrupt kernel data structures from a CPL=3 context via a bug in a syscall handler. Privilege escalation = ring 3 → ring 0.

Modern x86\_64 also has **SMEP** (Supervisor Mode Execution Prevention) and **SMAP** (Supervisor Mode Access Prevention), CPU features that stop ring-0 code from executing or (for SMAP) even touching ring-3 memory unless explicitly permitted. These exist *specifically* to kill classic kernel exploitation techniques (jumping to shellcode mapped in userspace). You will fight these directly once you get into kernel exploitation.

***

### 3. How you cross from Ring 3 to Ring 0: syscalls

On x86\_64 Linux, the standard mechanism is the `syscall` instruction (a special fast instruction, replacing the old `int 0x80` software interrupt used on 32-bit x86).

<figure><img src="/files/1TAPhQg35UKtV8VeCvLi" alt=""><figcaption></figcaption></figure>

```
 User process                          Kernel
 ─────────────                         ──────
 mov rax, 1        ; syscall number for write()
 mov rdi, 1        ; fd = stdout
 mov rsi, buf
 mov rdx, len
 syscall           ─────────────────►  CPU switches CPL 3→0,
                                        jumps to entry_SYSCALL_64
                                        (address loaded from MSR
                                         LSTAR at boot)
                                        kernel looks up rax in
                                        sys_call_table[],
                                        runs sys_write()
                                        sets return value in rax
 (execution resumes, CPL 0→3) ◄───────  sysretq
```

This `sys_call_table` is a juicy classic exploitation target, overwriting an entry there was a historical rootkit/exploit technique (mostly closed off now by `CONFIG_STRICT_KERNEL_RWX`, read-only mappings, and kernel lockdown).

Each syscall has a fixed number (see `/usr/include/asm/unistd_64.h` or `arch/x86/entry/syscalls/syscall_64.tbl` in kernel source).

***

### 4. Address space split (x86\_64, default config)

On a 64-bit Linux system, the full 64-bit virtual address space is split so that **the kernel is mapped into every process's page tables**, just marked "supervisor only" so ring-3 code can't touch it (until Meltdown showed you sometimes could, hence KPTI, see file 04).

```
0xFFFFFFFFFFFFFFFF ┐
                    │   Kernel space (~128 TB)
                    │   - kernel text/data
                    │   - vmalloc area
                    │   - direct-mapped physical memory
0xFFFF800000000000 ┘
        (non-canonical gap — only 48 of 64 bits are
         actually usable on typical CPUs, sign-extended)
0x00007FFFFFFFFFFF ┐
                    │   User space (~128 TB)
                    │   - stack (grows down)
                    │   - mmap'd libraries, heap
                    │   - .bss / .data / .text of the binary
0x0000000000000000 ┘
```

<figure><img src="/files/LFLH8sJX2ts7Rv0S5idd" alt=""><figcaption></figcaption></figure>

This is why a **NULL pointer dereference in the kernel** used to be so dangerous:&#x20;

<figure><img src="/files/xemnFMxSUAuKTjjlTc6r" alt=""><figcaption></figcaption></figure>

address `0x0` was mappable by an unprivileged user in userspace, so an attacker could `mmap()` page 0, place fake data/code there, then trigger a kernel bug that dereferences a NULL pointer, the kernel ends up reading/executing attacker-controlled data. Mitigated today by `mmap_min_addr` sysctl (blocks mapping low addresses) and SMAP.

<figure><img src="/files/3AKMtJAMrWDiswww5scN" alt=""><figcaption></figcaption></figure>

***

### 5. Kernel space layout in a bit more detail

```
 High addresses
 ┌────────────────────────────┐
 │ Fixmap / vsyscall           │
 ├────────────────────────────┤
 │ Modules area (loaded .ko)   │  <- kernel modules land here
 ├────────────────────────────┤
 │ vmalloc/ioremap space       │  <- non-contiguous kernel allocations
 ├────────────────────────────┤
 │ Direct mapping of all RAM   │  <- physical mem at fixed offset
 │ (PAGE_OFFSET, e.g.          │     (kernel can address any physical
 │  0xffff888000000000)        │      page just by adding an offset)
 ├────────────────────────────┤
 │ Kernel text (code) + data   │  <- the compiled kernel image itself
 └────────────────────────────┘
 Low addresses (kernel view)
```

The **direct mapping** is important: instead of the kernel having to set up page tables for every physical page it wants to touch, all of physical RAM is mapped once at a constant offset. `virt = phys + PAGE_OFFSET`. This is a huge deal in heap exploitation (kernel UAF/heap overflow bugs) since it means kernel objects sit inside a very predictable, large virtual range.

***

### 6. Kernel subsystems map (who owns what)

| Subsystem                                    | Responsibility                             | Key structures                                        |
| -------------------------------------------- | ------------------------------------------ | ----------------------------------------------------- |
| Process scheduler                            | decides which task runs on which CPU, when | `task_struct`, `sched_entity`, run queues             |
| Memory management (mm)                       | virtual memory, paging, allocators         | `mm_struct`, `vm_area_struct`, page tables, SLUB/SLAB |
| VFS + filesystems(Linux virtual file system) | uniform file interface over many FS types  | `inode`, `dentry`, `file`, `super_block`              |
| Block layer                                  | talks to disks, I/O scheduling             | `struct request`, `bio`                               |
| Network stack                                | sockets, protocols, netfilter              | `sk_buff`, `sock`, `net_device`                       |
| IPC                                          | pipes, signals, shared memory, sockets     | `pipe_inode_info`, signal structs                     |
| Device drivers                               | hardware-specific code                     | driver model, `struct device`                         |
| Security (LSM)                               | mandatory access control hooks             | SELinux/AppArmor hooks, capabilities                  |

Some terms:

<figure><img src="/files/ZtiKrajaFGCSfcEajdns" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/D1inpClNvwKb79uhOX77" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Gb6cALqjWrYDq4Sm5SWX" alt=""><figcaption></figcaption></figure>

Every one of these is a potential attack surface reachable via syscalls, `ioctl()`, netlink sockets, or `/proc` and `/sys` file interfaces, which is exactly why kernel fuzzers (syzkaller) hammer syscalls so heavily.

***

### 7. What's coming in the rest of this series

* **02-boot-process.md** — firmware → bootloader → kernel → PID 1, in detail
* **03-process-and-scheduling.md** — `task_struct`, fork/exec, context switch, scheduler
* **04-memory-management.md** — paging, page tables, MMU on x86\_64, SLUB, KASLR, KPTI
* **05-filesystem-management.md** — VFS, inodes/dentries, ext4 on-disk layout, mounting
* **06-networking.md** — socket layer, `sk_buff` journey, netfilter, packet walk

Each file builds on this one — the ring 0/ring 3 split and syscall boundary from this file is the spine of everything else.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/linux-internals/01.-linux-architecture-overview-x86-x86_64.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
