summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/rpc/clnt_vc.c16
-rw-r--r--lib/libc/rpc/svc_vc.c23
-rw-r--r--sbin/mount_portalfs/activate.c8
-rw-r--r--sys/kern/uipc_socket.c27
-rw-r--r--sys/kern/uipc_usrreq.c437
-rw-r--r--sys/netgraph/ng_socket.c4
-rw-r--r--sys/sys/domain.h2
-rw-r--r--sys/sys/un.h2
-rw-r--r--usr.sbin/mount_portalfs/activate.c8
-rw-r--r--usr.sbin/ppp/bundle.c10
10 files changed, 320 insertions, 217 deletions
diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c
index 6cdaad1..d2d0178 100644
--- a/lib/libc/rpc/clnt_vc.c
+++ b/lib/libc/rpc/clnt_vc.c
@@ -793,7 +793,10 @@ __msgread(sock, buf, cnt)
{
struct iovec iov[1];
struct msghdr msg;
- struct cmessage cm;
+ union {
+ struct cmsghdr cmsg;
+ char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+ } cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
@@ -804,7 +807,7 @@ __msgread(sock, buf, cnt)
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
- msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct cmsgcred));
msg.msg_flags = 0;
return(_recvmsg(sock, &msg, 0));
@@ -818,7 +821,10 @@ __msgwrite(sock, buf, cnt)
{
struct iovec iov[1];
struct msghdr msg;
- struct cmessage cm;
+ union {
+ struct cmsghdr cmsg;
+ char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+ } cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
@@ -826,14 +832,14 @@ __msgwrite(sock, buf, cnt)
cm.cmsg.cmsg_type = SCM_CREDS;
cm.cmsg.cmsg_level = SOL_SOCKET;
- cm.cmsg.cmsg_len = sizeof(struct cmessage);
+ cm.cmsg.cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
- msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct cmsgcred));
msg.msg_flags = 0;
return(_sendmsg(sock, &msg, 0));
diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c
index 052678b..95b907a 100644
--- a/lib/libc/rpc/svc_vc.c
+++ b/lib/libc/rpc/svc_vc.c
@@ -400,8 +400,6 @@ read_vc(xprtp, buf, len)
struct pollfd pollfd;
struct sockaddr *sa;
struct cmessage *cm;
- struct cmsghdr *cmp;
- struct sockcred *sc;
xprt = (SVCXPRT *)(void *)xprtp;
assert(xprt != NULL);
@@ -429,9 +427,7 @@ read_vc(xprtp, buf, len)
if (sa->sa_family == AF_LOCAL) {
cm = (struct cmessage *)xprt->xp_verf.oa_base;
if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) {
- cmp = &cm->cmsg;
- sc = (struct sockcred *)(void *)CMSG_DATA(cmp);
- xprt->xp_p2 = sc;
+ xprt->xp_p2 = &cm->cmcred;
return (len);
}
} else {
@@ -638,8 +634,14 @@ __msgread_withcred(sock, buf, cnt, cmp)
{
struct iovec iov[1];
struct msghdr msg;
+ union {
+ struct cmsghdr cmsg;
+ char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+ } cm;
+ int ret;
+
- bzero(cmp, sizeof(*cmp));
+ bzero(&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
@@ -647,11 +649,14 @@ __msgread_withcred(sock, buf, cnt, cmp)
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
- msg.msg_control = cmp;
- msg.msg_controllen = sizeof(struct cmessage);
+ msg.msg_control = &cm;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct cmsgcred));
msg.msg_flags = 0;
- return(_recvmsg(sock, &msg, 0));
+ ret = _recvmsg(sock, &msg, 0);
+ bcopy(&cm.cmsg, &cmp->cmsg, sizeof(cmp->cmsg));
+ bcopy(CMSG_DATA(&cm), &cmp->cmcred, sizeof(cmp->cmcred));
+ return ret;
}
static int
diff --git a/sbin/mount_portalfs/activate.c b/sbin/mount_portalfs/activate.c
index 5646498..6143620 100644
--- a/sbin/mount_portalfs/activate.c
+++ b/sbin/mount_portalfs/activate.c
@@ -113,9 +113,9 @@ int error;
int n;
struct iovec iov;
struct msghdr msg;
- struct {
+ union {
struct cmsghdr cmsg;
- int fd;
+ char control[CMSG_SPACE(sizeof(int))];
} ctl;
/*
@@ -137,10 +137,10 @@ int error;
* construct a suitable rights control message.
*/
if (fd >= 0) {
- ctl.fd = fd;
- ctl.cmsg.cmsg_len = sizeof(ctl);
+ ctl.cmsg.cmsg_len = CMSG_LEN(sizeof(int));
ctl.cmsg.cmsg_level = SOL_SOCKET;
ctl.cmsg.cmsg_type = SCM_RIGHTS;
+ *((int *)CMSG_DATA(&ctl.cmsg)) = fd;
msg.msg_control = (caddr_t) &ctl;
msg.msg_controllen = ctl.cmsg.cmsg_len;
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index a54dcff..0b40522 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -672,7 +672,7 @@ soreceive(so, psa, uio, mp0, controlp, flagsp)
struct mbuf **controlp;
int *flagsp;
{
- register struct mbuf *m, **mp;
+ struct mbuf *m, **mp;
register int flags, len, error, s, offset;
struct protosw *pr = so->so_proto;
struct mbuf *nextrecord;
@@ -798,23 +798,22 @@ dontblock:
m = m->m_next;
} else {
sbfree(&so->so_rcv, m);
- if (controlp) {
- if (pr->pr_domain->dom_externalize &&
- mtod(m, struct cmsghdr *)->cmsg_type ==
- SCM_RIGHTS)
- error = (*pr->pr_domain->dom_externalize)(m);
+ so->so_rcv.sb_mb = m->m_next;
+ m->m_next = NULL;
+ if (pr->pr_domain->dom_externalize)
+ error =
+ (*pr->pr_domain->dom_externalize)(m, controlp);
+ else if (controlp)
*controlp = m;
- so->so_rcv.sb_mb = m->m_next;
- m->m_next = 0;
- m = so->so_rcv.sb_mb;
- } else {
- MFREE(m, so->so_rcv.sb_mb);
- m = so->so_rcv.sb_mb;
- }
+ else
+ m_freem(m);
+ m = so->so_rcv.sb_mb;
}
if (controlp) {
orig_resid = 0;
- controlp = &(*controlp)->m_next;
+ do
+ controlp = &(*controlp)->m_next;
+ while (*controlp != NULL);
}
}
if (m) {
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 52c60cf..7480773 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -90,7 +90,8 @@ static void unp_gc __P((void));
static void unp_scan __P((struct mbuf *, void (*)(struct file *)));
static void unp_mark __P((struct file *));
static void unp_discard __P((struct file *));
-static int unp_internalize __P((struct mbuf *, struct thread *));
+static void unp_freerights __P((struct file **, int));
+static int unp_internalize __P((struct mbuf **, struct thread *));
static int unp_listen __P((struct unpcb *, struct proc *));
static int
@@ -274,7 +275,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
goto release;
}
- if (control && (error = unp_internalize(control, td)))
+ if (control && (error = unp_internalize(&control, td)))
goto release;
switch (so->so_type) {
@@ -952,80 +953,127 @@ unp_drain()
}
#endif
+static void
+unp_freerights(rp, fdcount)
+ struct file **rp;
+ int fdcount;
+{
+ int i;
+ struct file *fp;
+
+ for (i = 0; i < fdcount; i++) {
+ fp = *rp;
+ /*
+ * zero the pointer before calling
+ * unp_discard since it may end up
+ * in unp_gc()..
+ */
+ *rp++ = 0;
+ unp_discard(fp);
+ }
+}
+
int
-unp_externalize(rights)
- struct mbuf *rights;
+unp_externalize(control, controlp)
+ struct mbuf *control, **controlp;
{
struct thread *td = curthread; /* XXX */
- register int i;
- register struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
- register int *fdp;
- register struct file **rp;
- register struct file *fp;
- int newfds = (cm->cmsg_len - (CMSG_DATA(cm) - (u_char *)cm))
- / sizeof (struct file *);
+ struct cmsghdr *cm = mtod(control, struct cmsghdr *);
+ int i;
+ int *fdp;
+ struct file **rp;
+ struct file *fp;
+ void *data;
+ socklen_t clen = control->m_len, datalen;
+ int error, newfds;
int f;
+ u_int newlen;
- /*
- * if the new FD's will not fit, then we free them all
- */
- if (!fdavail(td, newfds)) {
- rp = (struct file **)CMSG_DATA(cm);
- for (i = 0; i < newfds; i++) {
- fp = *rp;
+ error = 0;
+ if (controlp != NULL) /* controlp == NULL => free control messages */
+ *controlp = NULL;
+
+ while (cm != NULL) {
+ if (sizeof(*cm) > clen || cm->cmsg_len > clen) {
+ error = EINVAL;
+ break;
+ }
+
+ data = CMSG_DATA(cm);
+ datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
+
+ if (cm->cmsg_level == SOL_SOCKET
+ && cm->cmsg_type == SCM_RIGHTS) {
+ newfds = datalen / sizeof(struct file *);
+ rp = data;
+
+ /* If we're not outputting the discriptors free them. */
+ if (error || controlp == NULL) {
+ unp_freerights(rp, newfds);
+ goto next;
+ }
+ /* if the new FD's will not fit free them. */
+ if (!fdavail(td, newfds)) {
+ error = EMSGSIZE;
+ unp_freerights(rp, newfds);
+ goto next;
+ }
/*
- * zero the pointer before calling unp_discard,
- * since it may end up in unp_gc()..
+ * now change each pointer to an fd in the global
+ * table to an integer that is the index to the
+ * local fd table entry that we set up to point
+ * to the global one we are transferring.
*/
- *rp++ = 0;
- unp_discard(fp);
- }
- return (EMSGSIZE);
- }
- /*
- * now change each pointer to an fd in the global table to
- * an integer that is the index to the local fd table entry
- * that we set up to point to the global one we are transferring.
- * If sizeof (struct file *) is bigger than or equal to sizeof int,
- * then do it in forward order. In that case, an integer will
- * always come in the same place or before its corresponding
- * struct file pointer.
- * If sizeof (struct file *) is smaller than sizeof int, then
- * do it in reverse order.
- */
- if (sizeof (struct file *) >= sizeof (int)) {
- fdp = (int *)(cm + 1);
- rp = (struct file **)CMSG_DATA(cm);
- for (i = 0; i < newfds; i++) {
- if (fdalloc(td, 0, &f))
- panic("unp_externalize");
- fp = *rp++;
- td->td_proc->p_fd->fd_ofiles[f] = fp;
- fp->f_msgcount--;
- unp_rights--;
- *fdp++ = f;
+ newlen = newfds * sizeof(int);
+ *controlp = sbcreatecontrol(NULL, newlen,
+ SCM_RIGHTS, SOL_SOCKET);
+ if (*controlp == NULL) {
+ error = E2BIG;
+ unp_freerights(rp, newfds);
+ goto next;
+ }
+
+ fdp = (int *)
+ CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+ for (i = 0; i < newfds; i++) {
+ if (fdalloc(td, 0, &f))
+ panic("unp_externalize fdalloc failed");
+ fp = *rp++;
+ td->td_proc->p_fd->fd_ofiles[f] = fp;
+ fp->f_msgcount--;
+ unp_rights--;
+ *fdp++ = f;
+ }
+ } else { /* We can just copy anything else across */
+ if (error || controlp == NULL)
+ goto next;
+ *controlp = sbcreatecontrol(NULL, datalen,
+ cm->cmsg_type, cm->cmsg_level);
+ if (*controlp == NULL) {
+ error = ENOBUFS;
+ goto next;
+ }
+ bcopy(data,
+ CMSG_DATA(mtod(*controlp, struct cmsghdr *)),
+ datalen);
}
- } else {
- fdp = (int *)(cm + 1) + newfds - 1;
- rp = (struct file **)CMSG_DATA(cm) + newfds - 1;
- for (i = 0; i < newfds; i++) {
- if (fdalloc(td, 0, &f))
- panic("unp_externalize");
- fp = *rp--;
- td->td_proc->p_fd->fd_ofiles[f] = fp;
- fp->f_msgcount--;
- unp_rights--;
- *fdp-- = f;
+
+ controlp = &(*controlp)->m_next;
+
+next:
+ if (CMSG_SPACE(datalen) < clen) {
+ clen -= CMSG_SPACE(datalen);
+ cm = (struct cmsghdr *)
+ ((caddr_t)cm + CMSG_SPACE(datalen));
+ } else {
+ clen = 0;
+ cm = NULL;
}
}
- /*
- * Adjust length, in case sizeof(struct file *) and sizeof(int)
- * differs.
- */
- cm->cmsg_len = CMSG_LEN(newfds * sizeof(int));
- rights->m_len = cm->cmsg_len;
- return (0);
+ m_freem(control);
+
+ return (error);
}
void
@@ -1043,109 +1091,134 @@ unp_init(void)
#endif
static int
-unp_internalize(control, td)
- struct mbuf *control;
+unp_internalize(controlp, td)
+ struct mbuf **controlp;
struct thread *td;
{
+ struct mbuf *control = *controlp;
struct proc *p = td->td_proc;
struct filedesc *fdescp = p->p_fd;
- register struct cmsghdr *cm = mtod(control, struct cmsghdr *);
- register struct file **rp;
- register struct file *fp;
- register int i, fd, *fdp;
- register struct cmsgcred *cmcred;
- int oldfds;
+ struct cmsghdr *cm = mtod(control, struct cmsghdr *);
+ struct cmsgcred *cmcred;
+ struct file **rp;
+ struct file *fp;
+ struct timeval *tv;
+ int i, fd, *fdp;
+ void *data;
+ socklen_t clen = control->m_len, datalen;
+ int error, oldfds;
u_int newlen;
- if ((cm->cmsg_type != SCM_RIGHTS && cm->cmsg_type != SCM_CREDS) ||
- cm->cmsg_level != SOL_SOCKET || cm->cmsg_len != control->m_len)
- return (EINVAL);
+ error = 0;
+ *controlp = NULL;
- /*
- * Fill in credential information.
- */
- if (cm->cmsg_type == SCM_CREDS) {
- cmcred = (struct cmsgcred *)(cm + 1);
- cmcred->cmcred_pid = p->p_pid;
- cmcred->cmcred_uid = p->p_ucred->cr_ruid;
- cmcred->cmcred_gid = p->p_ucred->cr_rgid;
- cmcred->cmcred_euid = p->p_ucred->cr_uid;
- cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups,
+ while (cm != NULL) {
+ if (sizeof(*cm) > clen || cm->cmsg_level != SOL_SOCKET
+ || cm->cmsg_len > clen) {
+ error = EINVAL;
+ goto out;
+ }
+
+ data = CMSG_DATA(cm);
+ datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
+
+ switch (cm->cmsg_type) {
+ /*
+ * Fill in credential information.
+ */
+ case SCM_CREDS:
+ *controlp = sbcreatecontrol(NULL, sizeof(*cmcred),
+ SCM_CREDS, SOL_SOCKET);
+ if (*controlp == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+
+ cmcred = (struct cmsgcred *)
+ CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+ cmcred->cmcred_pid = p->p_pid;
+ cmcred->cmcred_uid = p->p_ucred->cr_ruid;
+ cmcred->cmcred_gid = p->p_ucred->cr_rgid;
+ cmcred->cmcred_euid = p->p_ucred->cr_uid;
+ cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups,
CMGROUP_MAX);
- for (i = 0; i < cmcred->cmcred_ngroups; i++)
- cmcred->cmcred_groups[i] = p->p_ucred->cr_groups[i];
- return(0);
- }
+ for (i = 0; i < cmcred->cmcred_ngroups; i++)
+ cmcred->cmcred_groups[i] =
+ p->p_ucred->cr_groups[i];
+ break;
- oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);
- /*
- * check that all the FDs passed in refer to legal OPEN files
- * If not, reject the entire operation.
- */
- fdp = (int *)(cm + 1);
- for (i = 0; i < oldfds; i++) {
- fd = *fdp++;
- if ((unsigned)fd >= fdescp->fd_nfiles ||
- fdescp->fd_ofiles[fd] == NULL)
- return (EBADF);
- }
- /*
- * Now replace the integer FDs with pointers to
- * the associated global file table entry..
- * Allocate a bigger buffer as necessary. But if an cluster is not
- * enough, return E2BIG.
- */
- newlen = CMSG_LEN(oldfds * sizeof(struct file *));
- if (newlen > MCLBYTES)
- return (E2BIG);
- if (newlen - control->m_len > M_TRAILINGSPACE(control)) {
- if (control->m_flags & M_EXT)
- return (E2BIG);
- MCLGET(control, M_TRYWAIT);
- if ((control->m_flags & M_EXT) == 0)
- return (ENOBUFS);
-
- /* copy the data to the cluster */
- memcpy(mtod(control, char *), cm, cm->cmsg_len);
- cm = mtod(control, struct cmsghdr *);
- }
+ case SCM_RIGHTS:
+ oldfds = datalen / sizeof (int);
+ /*
+ * check that all the FDs passed in refer to legal files
+ * If not, reject the entire operation.
+ */
+ fdp = data;
+ for (i = 0; i < oldfds; i++) {
+ fd = *fdp++;
+ if ((unsigned)fd >= fdescp->fd_nfiles ||
+ fdescp->fd_ofiles[fd] == NULL) {
+ error = EBADF;
+ goto out;
+ }
+ }
+ /*
+ * Now replace the integer FDs with pointers to
+ * the associated global file table entry..
+ */
+ newlen = oldfds * sizeof(struct file *);
+ *controlp = sbcreatecontrol(NULL, newlen,
+ SCM_RIGHTS, SOL_SOCKET);
+ if (*controlp == NULL) {
+ error = E2BIG;
+ goto out;
+ }
- /*
- * Adjust length, in case sizeof(struct file *) and sizeof(int)
- * differs.
- */
- control->m_len = cm->cmsg_len = newlen;
+ fdp = data;
+ rp = (struct file **)
+ CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+ for (i = 0; i < oldfds; i++) {
+ fp = fdescp->fd_ofiles[*fdp++];
+ *rp++ = fp;
+ fp->f_count++;
+ fp->f_msgcount++;
+ unp_rights++;
+ }
+ break;
- /*
- * Transform the file descriptors into struct file pointers.
- * If sizeof (struct file *) is bigger than or equal to sizeof int,
- * then do it in reverse order so that the int won't get until
- * we're done.
- * If sizeof (struct file *) is smaller than sizeof int, then
- * do it in forward order.
- */
- if (sizeof (struct file *) >= sizeof (int)) {
- fdp = (int *)(cm + 1) + oldfds - 1;
- rp = (struct file **)CMSG_DATA(cm) + oldfds - 1;
- for (i = 0; i < oldfds; i++) {
- fp = fdescp->fd_ofiles[*fdp--];
- *rp-- = fp;
- fp->f_count++;
- fp->f_msgcount++;
- unp_rights++;
+ case SCM_TIMESTAMP:
+ *controlp = sbcreatecontrol(NULL, sizeof(*tv),
+ SCM_TIMESTAMP, SOL_SOCKET);
+ if (*controlp == NULL) {
+ error = ENOBUFS;
+ goto out;
+ }
+ tv = (struct timeval *)
+ CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+ microtime(tv);
+ break;
+
+ default:
+ error = EINVAL;
+ goto out;
}
- } else {
- fdp = (int *)(cm + 1);
- rp = (struct file **)CMSG_DATA(cm);
- for (i = 0; i < oldfds; i++) {
- fp = fdescp->fd_ofiles[*fdp++];
- *rp++ = fp;
- fp->f_count++;
- fp->f_msgcount++;
- unp_rights++;
+
+ controlp = &(*controlp)->m_next;
+
+ if (CMSG_SPACE(datalen) < clen) {
+ clen -= CMSG_SPACE(datalen);
+ cm = (struct cmsghdr *)
+ ((caddr_t)cm + CMSG_SPACE(datalen));
+ } else {
+ clen = 0;
+ cm = NULL;
}
}
- return (0);
+
+out:
+ m_freem(control);
+
+ return (error);
}
static int unp_defer, unp_gcing;
@@ -1343,28 +1416,48 @@ unp_scan(m0, op)
register struct mbuf *m0;
void (*op) __P((struct file *));
{
- register struct mbuf *m;
- register struct file **rp;
- register struct cmsghdr *cm;
- register int i;
+ struct mbuf *m;
+ struct file **rp;
+ struct cmsghdr *cm;
+ void *data;
+ int i;
+ socklen_t clen, datalen;
int qfds;
while (m0) {
- for (m = m0; m; m = m->m_next)
- if (m->m_type == MT_CONTROL &&
- m->m_len >= sizeof(*cm)) {
- cm = mtod(m, struct cmsghdr *);
- if (cm->cmsg_level != SOL_SOCKET ||
- cm->cmsg_type != SCM_RIGHTS)
- continue;
- qfds = (cm->cmsg_len -
- (CMSG_DATA(cm) - (u_char *)cm))
- / sizeof (struct file *);
- rp = (struct file **)CMSG_DATA(cm);
- for (i = 0; i < qfds; i++)
- (*op)(*rp++);
- break; /* XXX, but saves time */
+ for (m = m0; m; m = m->m_next) {
+ if (m->m_type == MT_CONTROL)
+ continue;
+
+ cm = mtod(m, struct cmsghdr *);
+ clen = m->m_len;
+
+ while (cm != NULL) {
+ if (sizeof(*cm) > clen || cm->cmsg_len > clen)
+ break;
+
+ data = CMSG_DATA(cm);
+ datalen = (caddr_t)cm + cm->cmsg_len
+ - (caddr_t)data;
+
+ if (cm->cmsg_level == SOL_SOCKET &&
+ cm->cmsg_type == SCM_RIGHTS) {
+ qfds = datalen / sizeof (struct file *);
+ rp = data;
+ for (i = 0; i < qfds; i++)
+ (*op)(*rp++);
+ }
+
+ if (CMSG_SPACE(datalen) < clen) {
+ clen -= CMSG_SPACE(datalen);
+ cm = (struct cmsghdr *)
+ ((caddr_t)cm + CMSG_SPACE(datalen));
+ } else {
+ clen = 0;
+ cm = NULL;
+ }
}
+ }
m0 = m0->m_act;
}
}
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index a7e7e20..87924ce 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -583,7 +583,7 @@ ng_internalize(struct mbuf *control, struct thread *td)
}
/* Check there is only one FD. XXX what would more than one signify? */
- oldfds = (cm->cmsg_len - sizeof(*cm)) / sizeof(int);
+ oldfds = ((caddr_t)cm + cm->cmsg_len - (caddr_t)data) / sizeof (int);
if (oldfds != 1) {
TRAP_ERROR;
return (EINVAL);
@@ -591,7 +591,7 @@ ng_internalize(struct mbuf *control, struct thread *td)
/* Check that the FD given is legit. and change it to a pointer to a
* struct file. */
- fd = *(int *) (cm + 1);
+ fd = CMSG_DATA(cm);
if ((unsigned) fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[fd]) == NULL) {
return (EBADF);
diff --git a/sys/sys/domain.h b/sys/sys/domain.h
index 01a59f6..2ae9fba 100644
--- a/sys/sys/domain.h
+++ b/sys/sys/domain.h
@@ -52,7 +52,7 @@ struct domain {
void (*dom_init) /* initialize domain data structures */
__P((void));
int (*dom_externalize) /* externalize access rights */
- __P((struct mbuf *));
+ __P((struct mbuf *, struct mbuf **));
void (*dom_dispose) /* dispose of internalized rights */
__P((struct mbuf *));
struct protosw *dom_protosw, *dom_protoswNPROTOSW;
diff --git a/sys/sys/un.h b/sys/sys/un.h
index becf3ff..e4ce14c 100644
--- a/sys/sys/un.h
+++ b/sys/sys/un.h
@@ -59,7 +59,7 @@ int uipc_usrreq __P((struct socket *so, int req, struct mbuf *m,
struct mbuf *nam, struct mbuf *control));
int unp_connect2 __P((struct socket *so, struct socket *so2));
void unp_dispose __P((struct mbuf *m));
-int unp_externalize __P((struct mbuf *rights));
+int unp_externalize __P((struct mbuf *mbuf, struct mbuf **controlp));
void unp_init __P((void));
extern struct pr_usrreqs uipc_usrreqs;
#else /* !_KERNEL */
diff --git a/usr.sbin/mount_portalfs/activate.c b/usr.sbin/mount_portalfs/activate.c
index 5646498..6143620 100644
--- a/usr.sbin/mount_portalfs/activate.c
+++ b/usr.sbin/mount_portalfs/activate.c
@@ -113,9 +113,9 @@ int error;
int n;
struct iovec iov;
struct msghdr msg;
- struct {
+ union {
struct cmsghdr cmsg;
- int fd;
+ char control[CMSG_SPACE(sizeof(int))];
} ctl;
/*
@@ -137,10 +137,10 @@ int error;
* construct a suitable rights control message.
*/
if (fd >= 0) {
- ctl.fd = fd;
- ctl.cmsg.cmsg_len = sizeof(ctl);
+ ctl.cmsg.cmsg_len = CMSG_LEN(sizeof(int));
ctl.cmsg.cmsg_level = SOL_SOCKET;
ctl.cmsg.cmsg_type = SCM_RIGHTS;
+ *((int *)CMSG_DATA(&ctl.cmsg)) = fd;
msg.msg_control = (caddr_t) &ctl;
msg.msg_controllen = ctl.cmsg.cmsg_len;
}
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 6b76231..908a9a6 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -1364,8 +1364,8 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s)
return;
}
- fd = (int *)(cmsg + 1);
- nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int);
+ fd = (int *)CMSG_DATA(cmsg);
+ nfd = ((caddr_t)cmsg + cmsg->cmsg_len - (caddr_t)fd) / sizeof(int);
if (nfd < 2) {
log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n",
@@ -1457,7 +1457,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s)
void
bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
{
- char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * SEND_MAXFD)];
const char *constlock;
char *lock;
struct cmsghdr *cmsg;
@@ -1507,7 +1507,7 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
msg.msg_iovlen = 1;
msg.msg_iov = iov;
msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
+ msg.msg_controllen = CMSG_SPACE(sizeof(int) * nfd);
msg.msg_flags = 0;
cmsg = (struct cmsghdr *)cmsgbuf;
@@ -1516,7 +1516,7 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
cmsg->cmsg_type = SCM_RIGHTS;
for (f = 0; f < nfd; f++)
- *((int *)(cmsg + 1) + f) = fd[f];
+ *((int *)CMSG_DATA(cmsg) + f) = fd[f];
for (f = 1, expect = 0; f < niov; f++)
expect += iov[f].iov_len;
OpenPOWER on IntegriCloud