Commit b6a34399 authored by Niels Möller's avatar Niels Möller
Browse files

(CMSG_LEN): Fallback definition now includes

int alignment at the end of the header.
(pty_recv_message): Check that msg_controllen is large enough
before using CMSG_FIRSTHDR.

Rev: src/pty-helper.c:1.12
parent 7ae7bc64
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
/* At least Solaris 5.8 lacks CMSG_LEN and CMSG_SPACE. */ /* At least Solaris 5.8 lacks CMSG_LEN and CMSG_SPACE. */
#ifndef CMSG_LEN #ifndef CMSG_LEN
/* The safest way seems to be to extract the offset of the data */ # define CMSG_LEN(l) \
# define CMSG_LEN(l) ((size_t) CMSG_DATA((struct cmsghdr *) 0) + (l)) (((sizeof(struct cmsghdr) + sizeof(int) - 1) & ~(sizeof(int) - 1)) + (l))
#endif #endif
#ifndef CMSG_SPACE #ifndef CMSG_SPACE
...@@ -221,30 +221,33 @@ pty_recv_message(int socket, struct pty_message *message) ...@@ -221,30 +221,33 @@ pty_recv_message(int socket, struct pty_message *message)
return -1; return -1;
/* Process any ancillary data before examining the regular data */ /* Process any ancillary data before examining the regular data */
for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg))
{
if (cmsg->cmsg_level != SOL_SOCKET)
continue;
switch (cmsg->cmsg_type)
{
#if defined (SCM_CREDENTIALS)
case SCM_CREDENTIALS:
{
struct ucred *creds;
if (cmsg->cmsg_len != CMSG_LEN(sizeof(*creds)))
continue;
if (message->has_creds) /* On SunOS 5.8, CMSG_FIRSTHDR doesn't handle empty lists correctly */
/* Shouldn't be multiple credentials, but if there are, if (hdr.msg_controllen >= sizeof(struct cmsghdr))
ignore all but the first. */ for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg))
continue; {
if (cmsg->cmsg_level != SOL_SOCKET)
creds = (struct ucred *) CMSG_DATA(cmsg); continue;
message->creds.pid = creds->pid; switch (cmsg->cmsg_type)
message->creds.uid = creds->uid; {
message->creds.gid = creds->gid; #if defined (SCM_CREDENTIALS)
case SCM_CREDENTIALS:
{
struct ucred *creds;
if (cmsg->cmsg_len != CMSG_LEN(sizeof(*creds)))
continue;
if (message->has_creds)
/* Shouldn't be multiple credentials, but if there are,
ignore all but the first. */
continue;
creds = (struct ucred *) CMSG_DATA(cmsg);
message->creds.pid = creds->pid;
message->creds.uid = creds->uid;
message->creds.gid = creds->gid;
message->has_creds = 1; message->has_creds = 1;
break; break;
} }
...@@ -270,52 +273,52 @@ pty_recv_message(int socket, struct pty_message *message) ...@@ -270,52 +273,52 @@ pty_recv_message(int socket, struct pty_message *message)
break; break;
} }
#elif defined (SCM_UCRED) #elif defined (SCM_UCRED)
case SCM_UCRED: case SCM_UCRED:
{ {
ucred_t *creds; ucred_t *creds;
if (message->has_creds) if (message->has_creds)
/* Shouldn't be multiple credentials, but if there are, /* Shouldn't be multiple credentials, but if there are,
ignore all but the first. */ ignore all but the first. */
continue; continue;
creds = (ucred_t *) CMSG_DATA(cmsg); creds = (ucred_t *) CMSG_DATA(cmsg);
message->creds.pid = ucred_getpid(creds); message->creds.pid = ucred_getpid(creds);
message->creds.uid = ucred_geteuid(creds); message->creds.uid = ucred_geteuid(creds);
message->creds.gid = ucred_getegid(creds); message->creds.gid = ucred_getegid(creds);
message->has_creds = 1; message->has_creds = 1;
break; break;
} }
#endif #endif
case SCM_RIGHTS: case SCM_RIGHTS:
{ {
int *fd = (int *) CMSG_DATA(cmsg); int *fd = (int *) CMSG_DATA(cmsg);
int i = 0; int i = 0;
/* Is there any simple and portable way to get the number /* Is there any simple and portable way to get the number
of fd:s? */ of fd:s? */
if (message->fd == -1 && CMSG_LEN(message->fd) <= cmsg->cmsg_len) if (message->fd == -1 && CMSG_LEN(message->fd) <= cmsg->cmsg_len)
{ {
message->fd = fd[i++]; message->fd = fd[i++];
fprintf(stderr, "Got fd %d\n", message->fd); fprintf(stderr, "Got fd %d\n", message->fd);
} }
/* We want only one fd; if we receive any more, close /* We want only one fd; if we receive any more, close
them */ them */
for (; CMSG_LEN( (i+1) * sizeof(message->fd)) <= cmsg->cmsg_len; i++) for (; CMSG_LEN( (i+1) * sizeof(message->fd)) <= cmsg->cmsg_len; i++)
{ {
fprintf(stderr, "Got unwanted fd %d, closing\n", fd[i]); fprintf(stderr, "Got unwanted fd %d, closing\n", fd[i]);
close(fd[i]); close(fd[i]);
} }
}
default:
/* Ignore */
;
} }
default: }
/* Ignore */
;
}
}
if (res != sizeof(message->header)) if (res != sizeof(message->header))
{ {
if (message->fd != -1) if (message->fd != -1)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment