This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
recvmsg bug
- To: libc-hacker@cygnus.com
- Subject: recvmsg bug
- From: Thorsten Kukuk <kukuk@weber-eb.uni-paderborn.de>
- Date: Fri, 31 Jul 1998 15:51:00 +0200
- Reply-To: kukuk@weber-eb.uni-paderborn.de
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;
}