This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

recvmsg bug



Hello,

I have found a bug in the recvmsg wrapper. In the current version, we try at
first to check, if we have enough space, and if we use SCM_CREDS. The problem
is, that the data buffer is not initialized. We could not test before the
syscall if SCM_CREDS is used. The next is, we don't need to check for enough
space, because the kernel struct is smaller then the libc ucred struct. We have
to check it later. I have added a patch, which fixes it for me. But I doubt
that it is correct, because the space check is missing. And I think we
overwrite the data following after the SCM_CREDS part.

  Thorsten

 --
Thorsten Kukuk  kukuk@vt.uni-paderborn.de
                http://www-vt.uni-paderborn.de/~kukuk
Linux is like a Vorlon.  It is incredibly powerful, gives terse,
cryptic answers and has a lot of things going on in the background.
1998-07-31  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

        * sysdeps/unix/sysv/linux/recvmsg.c: Don't check for SCM_CREDS before
	  syscall.

--- glibc-2.0.95/sysdeps/unix/sysv/linux/recvmsg.c	Wed Jul 29 08:13:26 1998
+++ libc-work/sysdeps/unix/sysv/linux/recvmsg.c	Fri Jul 31 15:40:58 1998
@@ -39,53 +39,34 @@
 {
   struct cmsghdr *cm;
   int ret;
-  int found_creds = 0;
 
-  /* Must check for space first. */
+  ret = __syscall_recvmsg (fd, message, flags);
+
+  if (ret == -1)
+    return ret;
+
+  /* Postprocess the message control block for SCM_CREDS. */
   cm = CMSG_FIRSTHDR (message);
   while (cm)
     {
       if (cm->cmsg_type == SCM_CREDS)
 	{
-	  if (cm->cmsg_len < CMSG_SPACE (sizeof (struct cmsgcred)))
-	    {
-	      __set_errno (EINVAL);
-	      return -1;
-	    }
-	  found_creds = 1;
+	  struct cmsgcred *c = (struct cmsgcred *) CMSG_DATA (cm);
+	  struct __kernel_ucred u;
+	  int i;
+	  memcpy (&u, CMSG_DATA (cm), sizeof (struct __kernel_ucred));
+
+	  c->cmcred_pid = u.pid;
+	  c->cmcred_uid = u.uid;
+	  c->cmcred_gid = u.gid;
+
+	  c->cmcred_euid = -1;
+	  c->cmcred_ngroups = 0;
+	  for (i = 0; i < CMGROUP_MAX; i++)
+	    c->cmcred_groups[i] = -1;
 	}
       cm = CMSG_NXTHDR (message, cm);
     }
-
-
-  ret = __syscall_recvmsg (fd, message, flags);
-
-  if (ret == -1)
-    return ret;
-
-  /* Postprocess the message control block for SCM_CREDS. */
-  cm = CMSG_FIRSTHDR (message);
-  if (found_creds)
-    while (cm)
-      {
-	if (cm->cmsg_type == SCM_CREDS)
-	  {
-	    struct cmsgcred *c = (struct cmsgcred *) CMSG_DATA (cm);
-	    struct __kernel_ucred u;
-	    int i;
-	    memcpy (&u, CMSG_DATA (cm), sizeof (struct __kernel_ucred));
-
-	    c->cmcred_pid = u.pid;
-	    c->cmcred_uid = u.uid;
-	    c->cmcred_gid = u.gid;
-
-	    c->cmcred_euid = -1;
-	    c->cmcred_ngroups = 0;
-	    for (i = 0; i < CMGROUP_MAX; i++)
-	      c->cmcred_groups[i] = -1;
-	  }
-	cm = CMSG_NXTHDR (message, cm);
-      }
   return ret;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]