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
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x86 (i386) | 5 | i386 | sys_open |
| x64 (x86_64) | 2 | common | sys_open |
Historique noyau
Introduit dans Linux 1.0.
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.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.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) = 3strace 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.