Skip to content
/linux-syscalls

Réseau · Section 2

bind(2)

Assigne une adresse locale à une socket.

Signature

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr * addr, socklen_t addrlen);
sockfd
Descripteur retourné par socket() ; ne doit pas déjà être lié.
addr
Pointeur vers une struct sockaddr_* assortie à la famille de la socket (sockaddr_in pour AF_INET, sockaddr_in6, sockaddr_un, sockaddr_ll pour AF_PACKET, etc.).
addrlen
Taille de la struct pointée par addr. Utiliser sizeof(struct sockaddr_in) etc. ; pas strlen().

Description

bind() assigne l'adresse indiquée par addr à la socket désignée par sockfd. Pour les sockets AF_INET / AF_INET6 c'est l'IP + port local sur lequel la socket recevra (ou, pour une socket TCP qui se connecte, l'IP/port source ; généralement le noyau les choisit automatiquement). Pour AF_UNIX c'est le chemin du système de fichiers ou le nom en espace abstrait. Un serveur appelle typiquement socket() → bind() → listen() → accept() ; un client saute bind() et laisse le noyau choisir un port source éphémère au connect(). Lier un port privilégié (< 1024 en INET) requiert CAP_NET_BIND_SERVICE.

Numéros par architecture

ArchitectureNuméroABIPoint d'entrée
x86 (i386)361i386sys_bind
x64 (x86_64)49commonsys_bind
ARM64 (aarch64)200—sys_bind

Historique noyau

Introduit dans Linux 1.0.

  1. 1.0

    bind() est présent dans Linux depuis 1.0 avec la sémantique BSD.

  2. 3.9

    SO_REUSEPORT a été ajouté pour permettre à plusieurs sockets dans des processus différents de se lier au même port, le noyau hashant les connexions entrantes entre elles. Utilisé par nginx et HAProxy pour passer à l'échelle sur plusieurs cœurs sans goulot accept() unique.

seccomp & conteneurs

Docker default profile

Autorisé

Podman default profile

Autorisé

bind() est autorisé par les profils Docker / Podman. Le filtrage d'arguments par famille sockaddr n'en vaut généralement pas la complexité — le filtre socket() amont (n'autoriser que AF_INET / AF_UNIX) borne déjà la surface. La restriction intéressante est au niveau IP : les programmes BPF cgroup (BPF_CGROUP_INET4_BIND, BPF_CGROUP_INET6_BIND) peuvent refuser le bind sur des ports précis — les network policies Kubernetes et Cilium s'en servent pour un contrôle fin.

libseccomp

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(bind), 0);

Exemple strace

$ strace -e socket,bind,listen python3 -c 'import socket;s=socket.socket();s.bind(("127.0.0.1",0));s.listen(1)'
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
listen(3, 1)                                                   = 0

strace décode sockaddr_in / sockaddr_in6 / sockaddr_un complètement : sa_family, sin_addr, sin_port via htons(). Un bind() retournant -1 EADDRINUSE au démarrage d'un service est le diagnostic classique de « port déjà utilisé » — strace l'affiche immédiatement. -e network filtre les appels liés aux sockets.

Sécurité & observabilité

bind() sur un port privilégié (< 1024) est la raison canonique pour laquelle les démons tournent en root ou détiennent CAP_NET_BIND_SERVICE ; auditer quelles capacités sont abandonnées après bind() est une étape de durcissement standard. Un bind() AF_UNIX vers un emplacement inattendu peut être une porte dérobée ; sur les hôtes systemd, comparer aux sockets listées. Un bind() AF_PACKET épingle une socket brute à une interface — presque toujours un signe de sniff hors d'outils légitimes type tcpdump. Le tracepoint eBPF syscalls:sys_enter_bind plus le hook BPF cgroup inet_bind donnent une observabilité complète.

Erreurs

EACCES
Adresse protégée et appelant sans la capacité requise — typiquement CAP_NET_BIND_SERVICE pour les ports INET sous 1024, ou permissions sur le chemin AF_UNIX.
EADDRINUSE
Adresse déjà utilisée. Avec SO_REUSEADDR c'est relâché pour les sockets en TIME_WAIT ; avec SO_REUSEPORT, plusieurs sockets peuvent se lier simultanément pour répartir la charge.
EADDRNOTAVAIL
Adresse locale inexistante (par ex. IP non assignée à une interface).
EAFNOSUPPORT
Discordance de famille entre socket et addr.
EBADF
sockfd n'est pas un descripteur valide.
EINVAL
Socket déjà liée, ou addrlen incorrect pour la famille.
ENOTSOCK
sockfd n'est pas une socket.
EROFS
—

Syscalls liés