Subject: kern/16439: NFS clients running SunOS 4.1.4 can't connect() to AF_UNIX sockets
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bt@csfps.de>
List: netbsd-bugs
Date: 04/22/2002 04:03:59
>Number:         16439
>Category:       kern
>Synopsis:       NFS clients running SunOS 4.1.4 can't connect() to AF_UNIX sockets
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 22 04:04:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Volker Borchert
>Release:        1.5.1 with fix for #15495
>Organization:
>Environment:
NFS Server: Sparc-10/81 running NetBSD-1.5.1
NFS Client: Sparc-10/81 or Sparc-2 running SunOS-4.1.4,
            booting diskless off above mentioned server
>Description:
On a client running SunOS-4.1.4, connect() to a unix domain socket
on a file system mounted from a server running NetBSD-1.5.1 fails
with errno=38, "Socket operation on non-socket" even though a stat()
shortly before the connect() says the socket is indeed a socket.

>How-To-Repeat:
The following short program when run on the client, prints

@(#)usock.c 1.3 02/04/21 13:26:55
/dev/log is socket
connect(/dev/log): Socket operation on non-socket



/*
 *
 * NFS problem between NetBSD-1.5.1 server and SunOS-4.1.4 client
 *
 * DESCRIPTION:
 *
 * On a client running SunOS-4.1.4, connect() to a unix domain socket
 * on a file system mounted from a server running NetBSD-1.5.1 fails
 * with errno=38, "Socket operation on non-socket".
 *
 * IMPACT:
 *
 * Applications connect()ing to unix domain sockets will not work at
 * all, or not properly. On diskless clients, this affects essential
 * services like syslogd (/dev/log), lpr (/dev/lpd/printer) and X11
 * (/tmp/.X11-unix/X0).
 *
 * REPRODUCE:
 *
 * Run this program on a diskless SunOS-4.1.4 client that mounts
 * / (with /dev) from a NetBSD-1.5.1 server.
 *
 * FIX:
 *
 * None known.
 *
 * WORKAROUND:
 *
 * Force sockets onto filesystems of other type (tmpfs will do).
 *
 */

#define path "/dev/log"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

extern char *sys_errlist[];

int main () {
  struct sockaddr_un addr;
  int                desc;
  struct stat        stbf;

  fprintf (stderr, "%s\n", "@(#)usock.c 1.3 02/04/21 13:26:55");

  if (stat (path, &stbf) < 0) {
    fprintf (stderr, "stat(%s): %s\n", path, sys_errlist[errno]);
    return -1;
  }

  if (S_ISDIR (stbf.st_mode)) {
    fprintf (stderr, "%s is directory\n", path);
  }
  if (S_ISCHR (stbf.st_mode)) {
    fprintf (stderr, "%s is character special\n", path);
  }
  if (S_ISBLK (stbf.st_mode)) {
    fprintf (stderr, "%s is block special\n", path);
  }
  if (S_ISREG (stbf.st_mode)) {
    fprintf (stderr, "%s is regular\n", path);
  }
  if (S_ISLNK (stbf.st_mode)) {
    fprintf (stderr, "%s is symbolic link\n", path);
  }
  if (S_ISSOCK (stbf.st_mode)) {
    fprintf (stderr, "%s is socket\n", path);
  }
  if (S_ISFIFO (stbf.st_mode)) {
    fprintf (stderr, "%s is fifo/pipe\n", path);
  }

  desc = socket (AF_UNIX, SOCK_STREAM, 0);
  if (desc < 0) {
    fprintf (stderr, "socket(): %s\n", sys_errlist[errno]);
    return -1;
  }
  addr.sun_family = AF_UNIX;
  strcpy (addr.sun_path, path);
  if (connect (desc, (struct sockaddr *) &addr, sizeof (struct sockaddr_un)) < 0) {
    fprintf (stderr, "connect(%s): %s\n", path, sys_errlist[errno]);
    return -1;
  }
  return 0;
}


>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted: