On 1/29/2020 12:22 PM, Ken Brown wrote:
> I'll follow up with the program I used to test this patch series.

Attached.

$ gcc -Wall -o o_path_socket_test o_path_socket_test.c

$ ./o_path_socket_test.exe
The following calls should fail with EBADF:
read: OK
write: OK
fchmod: OK
fchown: OK
ioctl: OK
fgetxattr: OK
mmap: OK
sockatmark: OK

The following calls should fail with ENOTSOCK:
sendto: OK
recvfrom: OK
setsockopt: OK
getsockopt: OK
getpeereid: OK
connect: OK
accept: OK
accept4: OK
bind: OK
getsockname: OK
listen: OK
shutdown: OK
getpeername: OK
recv: OK
send: OK
recvmsg: OK
sendmsg: OK
bindresvport_sa: OK
bindresvport with NULL arg: OK
bindresvport with valid sin arg: OK

The following call should fail with EAFNOSUPPORT:
bindresvport with invalid sin arg: OK

The following calls should succeed:
fstat: OK
fstatvfs: OK
fcntl_dup: OK
fcntl_getfl: OK
fcntl_setfl: OK
fcntl_getfd: OK
fcntl_setfd: OK
close: OK
#define _GNU_SOURCE
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/statvfs.h>
#include <sys/xattr.h>
#include <sys/mman.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SOCK_PATH "/tmp/mysocket"

int
main ()
{
  struct sockaddr_un addr;
  struct stat t;
  struct statvfs sfs;
  int fd;

  /* Create socket file.  */
  if (unlink (SOCK_PATH) == -1  && errno != ENOENT)
    {
      perror ("unlink");
      exit (1);
    }
  fd = socket (AF_UNIX, SOCK_STREAM, 0);
  if (fd == -1)
    {
      perror ("socket");
      exit (1);
    }
  memset (&addr, 0, sizeof (struct sockaddr_un));
  addr.sun_family = AF_UNIX;
  strcpy (addr.sun_path, SOCK_PATH);
  if (bind (fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
    {
      perror ("bind");
      exit (1);
    }
  if (close (fd) == -1)
    {
      perror ("close");
      exit (1);
    }

  /* Reopen the socket file with O_PATH.  */
  fd = open (SOCK_PATH, O_PATH);
  if (fd == -1)
    {
      perror ("open");
      exit (1);
    }

  printf ("The following calls should fail with EBADF:\n");
  errno = 0;
  if (read (fd, NULL, 0) < 0 && errno == EBADF)
    printf ("read: OK\n");
  else
    perror ("read");

  errno = 0;
  if (write (fd, NULL, 0) < 0 && errno == EBADF)
    printf ("write: OK\n");
  else
    perror ("write");

  errno = 0;
  if (fchmod (fd, 0) < 0 && errno == EBADF)
    printf ("fchmod: OK\n");
  else
    perror ("fchmod");

  errno = 0;
  if (fchown (fd, -1, -1) < 0 && errno == EBADF)
    printf ("fchown: OK\n");
  else
    perror ("fchown");

  errno = 0;
  if (ioctl (fd, FIONBIO, NULL) < 0 && errno == EBADF)
    printf ("ioctl: OK\n");
  else
    perror ("ioctl");

  errno = 0;
  if (fgetxattr (fd, "", NULL, 0) < 0 && errno == EBADF)
    printf ("fgetxattr: OK\n");
  else
    perror ("fgetxattr");

  errno = 0;
  if (mmap (NULL, 1, 0, MAP_SHARED, fd, 0) == MAP_FAILED && errno == EBADF)
    printf ("mmap: OK\n");
  else
    perror ("mmap");

  errno = 0;
  if (sockatmark (fd) < 0 && errno == EBADF)
    printf ("sockatmark: OK\n");
  else
    perror ("sockatmark");

  printf ("\nThe following calls should fail with ENOTSOCK:\n");

  struct sockaddr to;
  errno = 0;
  if (sendto (fd, NULL, 0, 0, &to, 0) < 0 && errno == ENOTSOCK)
    printf ("sendto: OK\n");
  else
    perror ("sendto");

  socklen_t len;
  errno = 0;
  if (recvfrom (fd, NULL, 0, 0, &to, &len) < 0 && errno == ENOTSOCK)
    printf ("recvfrom: OK\n");
  else
    perror ("recvfrom");

  int optval = 1;
  errno = 0;
  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)) < 0
                  && errno == ENOTSOCK)
    printf ("setsockopt: OK\n");
  else
    perror ("setsockopt");

  len = sizeof (optval);
  errno = 0;
  if (getsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &optval, &len) < 0
      && errno == ENOTSOCK)
    printf ("getsockopt: OK\n");
  else
    perror ("getsockopt");

  uid_t uid;
  gid_t gid;
  errno = 0;
  if (getpeereid (fd, &uid, &gid) < 0 && errno == ENOTSOCK)
    printf ("getpeereid: OK\n");
  else
    perror ("getpeereid");

  struct sockaddr name;
  errno = 0;
  if (connect (fd, &name, 0) < 0 && errno == ENOTSOCK)
    printf ("connect: OK\n");
  else
    perror ("connect");

  errno = 0;
  if (accept (fd, &name, &len) < 0 && errno == ENOTSOCK)
    printf ("accept: OK\n");
  else
    perror ("accept");

  errno = 0;
  if (accept4 (fd, &name, &len, 0) < 0 && errno == ENOTSOCK)
    printf ("accept4: OK\n");
  else
    perror ("accept4");

  errno = 0;
  if (bind (fd, &name, 0) < 0 && errno == ENOTSOCK)
    printf ("bind: OK\n");
  else
    perror ("bind");

  errno = 0;
  if (getsockname (fd, &name, &len) < 0 && errno == ENOTSOCK)
    printf ("getsockname: OK\n");
  else
    perror ("getsockname");

  errno = 0;
  if (listen (fd, 0) < 0 && errno == ENOTSOCK)
    printf ("listen: OK\n");
  else
    perror ("listen");

  errno = 0;
  if (shutdown (fd, 0) < 0 && errno == ENOTSOCK)
    printf ("shutdown: OK\n");
  else
    perror ("shutdown");

  errno = 0;
  if (getpeername (fd, &name, &len) < 0 && errno == ENOTSOCK)
    printf ("getpeername: OK\n");
  else
    perror ("getpeername");

  errno = 0;
  if (recv (fd, NULL, 0, 0) < 0 && errno == ENOTSOCK)
    printf ("recv: OK\n");
  else
    perror ("recv");

  errno = 0;
  if (send (fd, NULL, 0, 0) < 0 && errno == ENOTSOCK)
    printf ("send: OK\n");
  else
    perror ("send");

  struct msghdr msg;
  errno = 0;
  if (recvmsg (fd, &msg, 0) < 0 && errno == ENOTSOCK)
    printf ("recvmsg: OK\n");
  else
    perror ("recvmsg");

  errno = 0;
  if (sendmsg (fd, &msg, 0) < 0 && errno == ENOTSOCK)
    printf ("sendmsg: OK\n");
  else
    perror ("sendmsg");

  errno = 0;
  if (bindresvport_sa (fd, NULL) < 0 && errno == ENOTSOCK)
    printf ("bindresvport_sa: OK\n");
  else
    perror ("bindresvport_sa");

  errno = 0;
  if (bindresvport (fd, NULL) < 0 && errno == ENOTSOCK)
    printf ("bindresvport with NULL arg: OK\n");
  else
    perror ("bindresvport with NULL arg");

  struct sockaddr_in sin;
  memset (&sin, 0, sizeof (sin));
  sin.sin_family = AF_INET;
  /* sin.sin_port = htons (80); */
  /* sin.sin_addr.s_addr = htonl (INADDR_ANY); */
  errno = 0;
  if (bindresvport (fd, &sin) < 0 && errno == ENOTSOCK)
    printf ("bindresvport with valid sin arg: OK\n");
  else
    perror ("bindresvport with valid sin arg");

  printf("\nThe following call should fail with EAFNOSUPPORT:\n");

  errno = 0;
  sin.sin_family = AF_LOCAL;
  if (bindresvport (fd, &sin) < 0 && errno == EAFNOSUPPORT)
    printf ("bindresvport with invalid sin arg: OK\n");
  else
    perror ("bindresvport with invalid sin arg");

  printf ("\nThe following calls should succeed:\n");

  if (fstat (fd, &t) < 0)
    perror ("fstat");
  else
    printf ("fstat: OK\n");

  if (fstatvfs (fd, &sfs) < 0)
    perror ("fstatvfs");
  else
    printf ("fstatvfs: OK\n");

  if (fcntl (fd, F_DUPFD, 0) < 0)
    perror ("fcntl_dup");
  else
    printf ("fcntl_dup: OK\n");

  int flags = fcntl (fd, F_GETFL);
  if (flags < 0)
    perror ("fcntl_getfl");
  else
    printf ("fcntl_getfl: OK\n");

  if (flags >= 0)
    {
      if (fcntl (fd, F_SETFL, flags) < 0)
        perror ("fcntl_setfl");
      else
        printf ("fcntl_setfl: OK\n");
    }

  flags = fcntl (fd, F_GETFD);
  if (flags < 0)
    perror ("fcntl_getfd");
  else
    printf ("fcntl_getfd: OK\n");

  if (flags >= 0)
    {
      if (fcntl (fd, F_SETFD, flags) < 0)
        perror ("fcntl_setfd");
      else
        printf ("fcntl_setfd: OK\n");
    }

  if (close (fd) < 0)
    perror ("close");
  else
    printf ("close: OK\n");
}

Reply via email to