Skip to content
/linux-syscalls

Network · Section 2

bind(2)

Assign a local address to a socket.

Signature

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr * addr, socklen_t addrlen);
sockfd
Descriptor returned by socket(); must not yet be bound.
addr
Pointer to a sockaddr_* struct matching the socket's family (sockaddr_in for AF_INET, sockaddr_in6, sockaddr_un, sockaddr_ll for AF_PACKET, etc.).
addrlen
Size of the struct pointed to by addr. Use sizeof(struct sockaddr_in) etc.; not strlen().

Description

bind() assigns the address specified by addr to the socket referred to by sockfd. For AF_INET / AF_INET6 sockets this is the local IP + port that the socket will receive packets on (or, for a connecting TCP socket, the source IP/port; usually the kernel picks these automatically). For AF_UNIX it is the filesystem path or abstract-namespace name. A server typically calls socket() → bind() → listen() → accept(); a client usually skips bind() and lets the kernel choose an ephemeral source port at connect() time. Binding to a privileged port (< 1024 on INET) requires CAP_NET_BIND_SERVICE.

Architecture mapping

ArchitectureNumberABIEntry point
x86 (i386)361i386sys_bind
x64 (x86_64)49commonsys_bind
ARM64 (aarch64)200sys_bind

Kernel history

Introduced in Linux 1.0.

  1. 1.0

    bind() has been part of Linux since 1.0 with BSD-style semantics.

  2. 3.9

    SO_REUSEPORT was added so multiple sockets in different processes can bind() to the same port and have the kernel hash incoming connections across them. Used by nginx and HAProxy to scale across cores without a single accept() bottleneck.

seccomp & containers

Docker default profile

Allowed

Podman default profile

Allowed

bind() is allowed by Docker / Podman default profiles. Argument filtering by sockaddr family is generally not worth the complexity — the upstream socket() filter (allow only AF_INET / AF_UNIX) already gates the surface. The interesting restriction is at the IP-layer: cgroup BPF programs (BPF_CGROUP_INET4_BIND, BPF_CGROUP_INET6_BIND) can deny binds to specific ports — Kubernetes network policies and Cilium use this for fine-grained control.

libseccomp

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

strace example

$ 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 decodes sockaddr_in / sockaddr_in6 / sockaddr_un fully: sa_family, sin_addr, sin_port via htons(). A bind() returning -1 EADDRINUSE during startup of a service is the classic 'port already in use' diagnostic — strace shows it immediately. -e network filters to the socket-related syscalls.

Security & observability

bind() to a privileged port (< 1024) is the canonical reason daemons run as root or hold CAP_NET_BIND_SERVICE; auditing which capabilities are dropped after bind() is a standard hardening step. AF_UNIX bind() to an unexpected filesystem location can be a backdoor; on systemd hosts compare against systemd-listed sockets. AF_PACKET bind() pins a raw socket to a specific interface — almost always an indicator of sniffing activity outside of legitimate tcpdump-style tools. eBPF tracepoint syscalls:sys_enter_bind plus the cgroup BPF inet_bind hook give complete observability.

Errors

EACCES
The address is protected and the caller lacks the necessary capability — typically CAP_NET_BIND_SERVICE for INET ports below 1024, or filesystem permissions for an AF_UNIX path.
EADDRINUSE
The address is already in use. With SO_REUSEADDR set, this is relaxed for TIME_WAIT sockets; with SO_REUSEPORT, multiple sockets can bind to the same port at once for load distribution.
EADDRNOTAVAIL
A non-existent local address was requested (e.g. an IP not assigned to any interface).
EAFNOSUPPORT
Address family mismatch between the socket and addr.
EBADF
sockfd is not a valid descriptor.
EINVAL
Socket is already bound, or addrlen is wrong for the family.
ENOTSOCK
sockfd is not a socket.
EROFS

Related syscalls