about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorPino Toscano <toscano.pino@tiscali.it>2012-07-20 23:56:58 +0200
committerPino Toscano <toscano.pino@tiscali.it>2012-07-20 23:56:58 +0200
commitac4ea442f3c70254def5c2f8aee592cddb5eef51 (patch)
tree7abc84097b5e9b7462dba181c619dffc6a2dcd3c /sysdeps
parent0f48659e36e72c091f988d9ea5a2dd505960ab0f (diff)
downloadglibc-ac4ea442f3c70254def5c2f8aee592cddb5eef51.tar.gz
glibc-ac4ea442f3c70254def5c2f8aee592cddb5eef51.tar.xz
glibc-ac4ea442f3c70254def5c2f8aee592cddb5eef51.zip
Hurd: sendto: do not crash when ADDR is null
Create a new create_address_port subroutine to isolate the address port creation
(for both local and remove sockets), and use it inside HURD_DPORT_USE.
Also intialize APORT to MACH_PORT_NULL and make sure to always deallocate it,
when not null.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/sendto.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/sysdeps/mach/hurd/sendto.c b/sysdeps/mach/hurd/sendto.c
index c641757dd7..bd4123ea10 100644
--- a/sysdeps/mach/hurd/sendto.c
+++ b/sysdeps/mach/hurd/sendto.c
@@ -33,37 +33,50 @@ __sendto (int fd,
 	  const struct sockaddr_un *addr,
 	  socklen_t addr_len)
 {
-  addr_port_t aport;
+  addr_port_t aport = MACH_PORT_NULL;
   error_t err;
   size_t wrote;
 
-  if (addr->sun_family == AF_LOCAL)
+  /* Get an address port for the desired destination address.  */
+  error_t create_address_port (io_t port,
+			       const struct sockaddr_un *addr,
+			       socklen_t addr_len,
+			       addr_port_t *aport)
     {
-      /* For the local domain, we must look up the name as a file and talk
-	 to it with the ifsock protocol.  */
-      file_t file = __file_name_lookup (addr->sun_path, 0, 0);
-      if (file == MACH_PORT_NULL)
-	return -1;
-      err = __ifsock_getsockaddr (file, &aport);
-      __mach_port_deallocate (__mach_task_self (), file);
-      if (err == MIG_BAD_ID || err == EOPNOTSUPP)
-	/* The file did not grok the ifsock protocol.  */
-	err = ENOTSOCK;
-      if (err)
-	return __hurd_fail (err);
+      error_t err_port;
+
+      if (addr->sun_family == AF_LOCAL)
+	{
+	  /* For the local domain, we must look up the name as a file and talk
+	     to it with the ifsock protocol.  */
+	  file_t file = __file_name_lookup (addr->sun_path, 0, 0);
+	  if (file == MACH_PORT_NULL)
+	    return errno;
+	  err_port = __ifsock_getsockaddr (file, aport);
+	  __mach_port_deallocate (__mach_task_self (), file);
+	  if (err_port == MIG_BAD_ID || err_port == EOPNOTSUPP)
+	    /* The file did not grok the ifsock protocol.  */
+	    err_port = ENOTSOCK;
+	}
+      else
+	{
+	  err_port = __socket_create_address (port,
+					      addr->sun_family,
+					      (char *) addr,
+					      addr_len,
+					      aport);
+	}
+
+      return err_port;
     }
-  else
-    err = EIEIO;
 
-  /* Get an address port for the desired destination address.  */
   err = HURD_DPORT_USE (fd,
 			({
-			  if (err)
-			    err = __socket_create_address (port,
-							   addr->sun_family,
-							   (char *) addr,
-							   addr_len,
-							   &aport);
+			  if (addr != NULL)
+			    err = create_address_port (port, addr, addr_len,
+						       &aport);
+			  else
+			    err = 0;
 			  if (! err)
 			    {
 			      /* Send the data.  */
@@ -72,12 +85,13 @@ __sendto (int fd,
 						   NULL,
 						   MACH_MSG_TYPE_COPY_SEND, 0,
 						   NULL, 0, &wrote);
-			      __mach_port_deallocate (__mach_task_self (),
-						      aport);
 			    }
 			  err;
 			}));
 
+  if (aport != MACH_PORT_NULL)
+    __mach_port_deallocate (__mach_task_self (), aport);
+
   return err ? __hurd_sockfail (fd, flags, err) : wrote;
 }