The Linux Abstract Socket Namespace

The so-called abstract namespace is a Linux-specific feature that allows us to bind a UNIX domain socket to a name without that name being created in the file system. This provides a few potential advantages:

To create an abstract binding, we specify the first byte of the sun_path field as a null byte (\0). This distinguishes abstract socket names from conventional UNIX domain socket pathnames, which consist of a string of one or more nonnull bytes terminated by a null byte. The name of the abstract socket is then defined by the remaining bytes (including any null bytes) in sun_path up to the length defined for the size of the address structure (i.e., addrlen - sizeof(sa_family_t)).

Example 57-8 demonstrates the creation of an abstract socket binding.

Example 57-8. Creating an abstract socket binding

from sockets/us_abstract_bind.c
    struct sockaddr_un addr;

    memset(&addr, 0, sizeof(struct sockaddr_un));  /* Clear address structure */
    addr.sun_family = AF_UNIX;                     /* UNIX domain address */

    /* addr.sun_path[0] has already been set to 0 by memset() */

    str = "xyz";         /* Abstract name is "\0xyz" */
    strncpy(&addr.sun_path[1], str, strlen (str));

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockfd == -1)
        errExit("socket");

    if (bind(sockfd, (struct sockaddr *) &addr,
            sizeof(sa_family_t) + strlen(str) + 1) == -1)
        errExit("bind");
                                                  from sockets/us_abstract_bind.c

The fact that an initial null byte is used to distinguish an abstract socket name from a conventional socket name can have an unusual consequence. Suppose that the variable name happens to point to a zero-length string and that we attempt to bind a UNIX domain socket to a sun_path initialized as follows:

strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1);

On Linux, we’ll inadvertently create an abstract socket binding. However, such a code sequence is probably unintentional (i.e., a bug). On other UNIX implementations, the subsequent bind() would fail.