Fix: explicitly send client credentials during handshake
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 17:35:40 +0000 (13:35 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 30 May 2017 16:39:26 +0000 (12:39 -0400)
The notification client does not send its credentials during
the handshake. However, the session daemon will still receive
them except in very rare, and hard to reproduce, cases.

It appears that the kernel will provide the credential cmsg
regardless of whether or not the client has actually sent them.

Inspecting the kernel source (af_unix.c) seems to indicate that
the credentials will be passed on sendmsg whenever one of the
sockets involved has set the SO_PASSCRED flag. It also seems to
maintain compatibility with applications that expect write() to
pass credentials by default. This explains why the explicit
passing didn't seem needed.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/notification-thread-events.c
src/lib/lttng-ctl/channel.c

index 8f250dfdd715f38da9020b746c4cfbb30321f6b0..793499c4eebb40218ceb1ac651d18b59a520edbe 100644 (file)
@@ -111,7 +111,7 @@ struct notification_client {
                         * Indicates whether or not credentials are expected
                         * from the client.
                         */
-                       bool receive_creds;
+                       bool expect_creds;
                        /*
                         * Indicates whether or not credentials were received
                         * from the client.
@@ -1171,7 +1171,6 @@ int client_reset_inbound_state(struct notification_client *client)
                        sizeof(struct lttng_notification_channel_message);
        client->communication.inbound.msg_type =
                        LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNKNOWN;
-       client->communication.inbound.receive_creds = false;
        LTTNG_SOCK_SET_UID_CRED(&client->communication.inbound.creds, -1);
        LTTNG_SOCK_SET_GID_CRED(&client->communication.inbound.creds, -1);
        ret = lttng_dynamic_buffer_set_size(
@@ -1197,6 +1196,7 @@ int handle_notification_thread_client_connect(
        CDS_INIT_LIST_HEAD(&client->condition_list);
        lttng_dynamic_buffer_init(&client->communication.inbound.buffer);
        lttng_dynamic_buffer_init(&client->communication.outbound.buffer);
+       client->communication.inbound.expect_creds = true;
        ret = client_reset_inbound_state(client);
        if (ret) {
                ERR("[notification-thread] Failed to reset client communication's inbound state");
@@ -1491,10 +1491,6 @@ int client_dispatch_message(struct notification_client *client,
                client->communication.inbound.bytes_to_receive = msg->size;
                client->communication.inbound.msg_type =
                                (enum lttng_notification_channel_message_type) msg->type;
-               if (client->communication.inbound.msg_type ==
-                               LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_HANDSHAKE) {
-                       client->communication.inbound.receive_creds = true;
-               }
                ret = lttng_dynamic_buffer_set_size(
                                &client->communication.inbound.buffer, msg->size);
                if (ret) {
@@ -1646,13 +1642,13 @@ int handle_notification_thread_client_in(
 
        offset = client->communication.inbound.buffer.size -
                        client->communication.inbound.bytes_to_receive;
-       if (client->communication.inbound.receive_creds) {
+       if (client->communication.inbound.expect_creds) {
                recv_ret = lttcomm_recv_creds_unix_sock(socket,
                                client->communication.inbound.buffer.data + offset,
                                client->communication.inbound.bytes_to_receive,
                                &client->communication.inbound.creds);
                if (recv_ret > 0) {
-                       client->communication.inbound.receive_creds = false;
+                       client->communication.inbound.expect_creds = false;
                        client->communication.inbound.creds_received = true;
                }
        } else {
index 5bfb75902e2ff98155884208668125ecd9db1799..3d48babb728351b3c05489b370419afbab415e6d 100644 (file)
@@ -444,7 +444,7 @@ int handshake(struct lttng_notification_channel *channel)
 
        pthread_mutex_lock(&channel->lock);
 
-       ret = lttcomm_send_unix_sock(channel->socket, send_buffer,
+       ret = lttcomm_send_creds_unix_sock(channel->socket, send_buffer,
                        sizeof(send_buffer));
        if (ret < 0) {
                goto end_unlock;
This page took 0.028509 seconds and 4 git commands to generate.