Skip to content
/linux-syscalls

Fichiers & E/S · Section 2

open(2)

Ouvre ou crée un fichier et renvoie un descripteur de fichier.

Signature

#include <fcntl.h>

int open(const char * pathname, int flags, mode_t mode);
pathname
Chemin du fichier à ouvrir. Absolu ou relatif au répertoire de travail du processus.
flags
OU bit-à-bit d'un mode d'accès (O_RDONLY, O_WRONLY ou O_RDWR) et de zéro ou plusieurs drapeaux de création/état (O_CREAT, O_CLOEXEC, O_NONBLOCK, etc.).
mode
Bits de permission appliqués uniquement lorsque O_CREAT ou O_TMPFILE est présent ; ignoré sinon. Soumis à l'umask du processus.

Description

open() ouvre le fichier désigné par pathname. Si le fichier n'existe pas et que O_CREAT est passé, il est créé avec les permissions indiquées par mode (modifiées par l'umask du processus). L'appel renvoie un descripteur de fichier non négatif en cas de succès, -1 et errno positionné sinon. Sur Linux moderne, open() est implémenté via openat() avec AT_FDCWD ; sur aarch64, open() n'existe pas comme appel système — seul openat() est exporté, et la libc effectue la traduction.

Numéros par architecture

ArchitectureNuméroABIPoint d'entrée
x86 (i386)5i386sys_open
x64 (x86_64)2commonsys_open

Historique noyau

Introduit dans Linux 1.0.

  1. 2.6.23

    O_CLOEXEC a été ajouté pour positionner close-on-exec de manière atomique à l'ouverture, supprimant une fenêtre de course qui imposait auparavant un appel séparé à fcntl(F_SETFD).

  2. 2.6.39

    O_PATH a été introduit pour obtenir un descripteur référant un emplacement du système de fichiers sans ouvrir le fichier sous-jacent — utile pour les opérations type fstatat et la transmission de descripteurs.

  3. 3.11

    O_TMPFILE a été ajouté pour créer atomiquement un fichier anonyme sous un répertoire ; il disparaît à la dernière fermeture, évitant les courses sur unlink().

seccomp & conteneurs

Docker default profile

Autorisé

Podman default profile

Autorisé

open() figure dans les profils par défaut de Docker et Podman. Un conteneur qui le retire doit aussi retirer openat()/openat2() — la libc moderne utilise openat() en interne. Cette restriction est très lourde et casse en pratique toute E/S.

libseccomp

scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0);
seccomp_load(ctx);

BPF filter (raw)

BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_open, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),

Exemple strace

$ strace -e openat,open ls /etc
openat(AT_FDCWD, "/etc", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3

strace affiche openat() pour la plupart des chemins même si le code source appelle open() — glibc réécrit l'appel. Utiliser -y pour résoudre les descripteurs en chemins, et -e trace=openat,open pour filtrer.

Sécurité & observabilité

Les rootkits hookent fréquemment open()/openat() pour masquer des fichiers à l'inspection userspace (LD_PRELOAD ou réécriture de la table des appels système). Côté noyau, les tracepoints eBPF sys_enter_openat et lsm/file_open sont les points d'observation canoniques ; auditd les capture via la règle openat. Surveiller les ouvertures de /proc/*/mem, /dev/kmem ou /sys/kernel/debug depuis des contextes non privilégiés.

Erreurs

EACCES
Accès refusé, ou O_CREAT spécifié sans permission de recherche sur un composant.
EEXIST
O_CREAT|O_EXCL spécifié et le fichier existe.
ENOENT
Un composant n'existe pas, ou O_CREAT absent et le fichier n'existe pas.
EISDIR
—
ENFILE
Limite système de la table des fichiers atteinte.
EMFILE
Limite par processus de descripteurs atteinte.
ENAMETOOLONG
—
ENOSPC
—
EROFS
—
ELOOP
—

Drapeaux

O_RDONLY
0
—
O_WRONLY
1
—
O_RDWR
2
—
O_CREAT
0100
Crée le fichier s'il n'existe pas ; requiert l'argument mode.
O_EXCL
0200
Combiné à O_CREAT, échoue si le fichier existe déjà (création atomique).
O_TRUNC
01000
—
O_APPEND
02000
—
O_NONBLOCK
04000
Ouverture non bloquante ; les E/S ultérieures ne bloqueront pas.
O_CLOEXEC
02000000
Positionne close-on-exec sur le nouveau descripteur — indispensable pour éviter les fuites de fd à travers execve().
O_DIRECTORY
0200000
—
O_PATH
010000000
Obtient un descripteur n'autorisant que les opérations sur l'arborescence (fstatat, openat) ; le fichier n'est pas ouvert.
O_TMPFILE
020200000
Crée un fichier temporaire anonyme sous le répertoire indiqué ; détruit à la fermeture.

Syscalls liés