Fix sending fd through sendmsg/recvmsg ancillary data
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Jul 2011 18:16:05 +0000 (14:16 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Jul 2011 18:16:05 +0000 (14:16 -0400)
ltt-kconsumerd was only reading a "char" rather than an integer. It
worked fine on little endian for values below 256, and failed on big
endian machines (always reading "0").

Also cleanup msg initialization.
Also perform final msg.msg_controllen = cmsg->cmsg_len; after memcpy, as
done in cmsg(3) example (extra safety).

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttkconsumerd/liblttkconsumerd.c
liblttsessiondcomm/liblttsessiondcomm.c

index 1e86d28d0cc1ea9cf6afecfb22f554b040ebef13..1d69a4c463faffc1fa764141e287f725a625c535 100644 (file)
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <urcu/list.h>
+#include <assert.h>
 
 #include "libkernelctl.h"
 #include "liblttkconsumerd.h"
@@ -585,7 +586,6 @@ static int kconsumerd_consumerd_recv_fd(int sfd,
                struct pollfd *kconsumerd_sockpoll, int size,
                enum kconsumerd_command cmd_type)
 {
-       struct msghdr msg;
        struct iovec iov[1];
        int ret = 0, i, tmp2;
        struct cmsghdr *cmsg;
@@ -596,8 +596,15 @@ static int kconsumerd_consumerd_recv_fd(int sfd,
        /* the number of fds we are about to receive */
        nb_fd = size / sizeof(struct lttcomm_kconsumerd_msg);
 
+       /*
+        * Note: only supporting receiving one FD at a time for now.
+        * This code needs fixing if we wish to receive more (a single
+        * receive for the whole fd batch rather than one per fd).
+        */
+       assert(nb_fd == 1);
+
        for (i = 0; i < nb_fd; i++) {
-               memset(&msg, 0, sizeof(msg));
+               struct msghdr msg = { 0 };
 
                /* Prepare to receive the structures */
                iov[0].iov_base = &lkm;
@@ -631,12 +638,13 @@ static int kconsumerd_consumerd_recv_fd(int sfd,
                        kconsumerd_send_error(KCONSUMERD_ERROR_RECV_FD);
                        goto end;
                }
+
                /* if we received fds */
                if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
                        switch (cmd_type) {
                        case ADD_STREAM:
-                               DBG("kconsumerd_add_fd %s (%d)", lkm.path_name, (CMSG_DATA(cmsg)[0]));
-                               ret = kconsumerd_add_fd(&lkm, (CMSG_DATA(cmsg)[0]));
+                               DBG("kconsumerd_add_fd %s (%d)", lkm.path_name, ((int *) CMSG_DATA(cmsg))[0]);
+                               ret = kconsumerd_add_fd(&lkm, ((int *) CMSG_DATA(cmsg))[0]);
                                if (ret < 0) {
                                        kconsumerd_send_error(KCONSUMERD_OUTFD_ERROR);
                                        goto end;
index 8fadccf1b884807cfe4ec88e68b6429ec5581eaa..253e63545addf17710baeecc679d37fa05d11aae 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <assert.h>
 
 #include "liblttsessiondcomm.h"
 
@@ -223,12 +224,10 @@ int lttcomm_listen_unix_sock(int sock)
  */
 ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
 {
-       struct msghdr msg;
+       struct msghdr msg = { 0 };
        struct iovec iov[1];
        ssize_t ret = -1;
 
-       memset(&msg, 0, sizeof(msg));
-
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
@@ -250,12 +249,10 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
  */
 ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
 {
-       struct msghdr msg;
+       struct msghdr msg = { 0 };
        struct iovec iov[1];
        ssize_t ret = -1;
 
-       memset(&msg, 0, sizeof(msg));
-
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
@@ -294,23 +291,29 @@ int lttcomm_close_unix_sock(int sock)
  */
 ssize_t lttcomm_send_fds_unix_sock(int sock, void *buf, int *fds, size_t nb_fd, size_t len)
 {
-       struct msghdr msg;
+       struct msghdr msg = { 0 };
        struct cmsghdr *cmptr;
        struct iovec iov[1];
        ssize_t ret = -1;
        unsigned int sizeof_fds = nb_fd * sizeof(int);
        char tmp[CMSG_SPACE(sizeof_fds)];
 
-       memset(&msg, 0, sizeof(msg));
+       /*
+        * Note: the consumerd receiver only supports receiving one FD at a
+        * time for now.
+        */
+       assert(nb_fd == 1);
 
        msg.msg_control = (caddr_t)tmp;
        msg.msg_controllen = CMSG_LEN(sizeof_fds);
 
        cmptr = CMSG_FIRSTHDR(&msg);
-       cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
        cmptr->cmsg_level = SOL_SOCKET;
        cmptr->cmsg_type = SCM_RIGHTS;
+       cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
        memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
+       /* Sum of the length of all control messages in the buffer: */
+       msg.msg_controllen = cmptr->cmsg_len;
 
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
This page took 0.028969 seconds and 5 git commands to generate.