Index: sys/compat/linux/linux.c =================================================================== --- sys/compat/linux/linux.c +++ sys/compat/linux/linux.c @@ -50,6 +50,7 @@ #include #include +#include #include struct futex_list futex_list; @@ -501,22 +502,26 @@ salen = sizeof(struct sockaddr_in); } - if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) { + if (bdom == AF_LOCAL) { hdrlen = offsetof(struct sockaddr_un, sun_path); name = ((struct sockaddr_un *)kosa)->sun_path; - if (*name == '\0') { + if (*name == '\0' && linux_abstract_pathnames) { /* * Linux abstract namespace starts with a NULL byte. - * XXX We do not support abstract namespace yet. + * By default we pretend they are ordinary pathnames. */ - namelen = strnlen(name + 1, salen - hdrlen - 1) + 1; - } else + namelen = strnlen(name + 1, salen - hdrlen - 1); + memmove(name, name + 1, namelen); + salen = hdrlen + namelen; + } else if (salen > sizeof(struct sockaddr_un)) { namelen = strnlen(name, salen - hdrlen); - salen = hdrlen + namelen; + salen = hdrlen + namelen; + } if (salen > sizeof(struct sockaddr_un)) { error = ENAMETOOLONG; goto out; } + } sa = (struct sockaddr *)kosa; Index: sys/compat/linux/linux_mib.h =================================================================== --- sys/compat/linux/linux_mib.h +++ sys/compat/linux/linux_mib.h @@ -62,6 +62,7 @@ #define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000) +extern bool linux_abstract_pathnames; extern int linux_debug; extern int linux_default_openfiles; extern int linux_default_stacksize; Index: sys/compat/linux/linux_mib.c =================================================================== --- sys/compat/linux/linux_mib.c +++ sys/compat/linux/linux_mib.c @@ -82,6 +82,11 @@ &linux_dummy_rlimits, 0, "Return dummy values for unsupported Linux-specific rlimits"); +bool linux_abstract_pathnames = 1; +SYSCTL_BOOL(_compat_linux, OID_AUTO, abstract_pathnames, CTLFLAG_RWTUN, + &linux_abstract_pathnames, 0, + "Handle abstract unix(7) sockets as pathnames"); + int linux_ignore_ip_recverr = 1; SYSCTL_INT(_compat_linux, OID_AUTO, ignore_ip_recverr, CTLFLAG_RWTUN, &linux_ignore_ip_recverr, 0, "Ignore enabling IP_RECVERR");