Don't close invalid or uninitialied fds
[src/drm-lease-manager.git] / libdlmclient / dlmclient.c
index 03c08a8..af7d3ac 100644 (file)
@@ -82,66 +82,27 @@ static bool lease_send_request(struct dlm_lease *lease, enum dlm_opcode opcode)
 
 static bool lease_recv_fd(struct dlm_lease *lease)
 {
-       char ctrl_buf[CMSG_SPACE(sizeof(int))] = {0};
-       char data[1] = {0};
-
-       struct iovec iov[1];
-       iov[0].iov_base = data;
-       iov[0].iov_len = sizeof(data);
-
-       struct msghdr msg = {
-           .msg_control = ctrl_buf,
-           .msg_controllen = CMSG_SPACE(sizeof(int)),
-           .msg_iov = iov,
-           .msg_iovlen = 1,
-       };
+       lease->lease_fd = receive_lease_fd(lease->dlm_server_sock);
 
-       int ret;
-       while ((ret = recvmsg(lease->dlm_server_sock, &msg, 0)) <= 0) {
-               if (ret == 0) {
-                       errno = EACCES;
-                       DEBUG_LOG("Request rejected by DRM lease manager\n");
-                       // TODO: Report why the request was rejected.
-                       return false;
-               }
-               if (errno != EINTR) {
-                       DEBUG_LOG("Socket data receive error: %s\n",
-                                 strerror(errno));
-                       return false;
-               }
-       }
+       if (lease->lease_fd < 0)
+               goto err;
 
-       lease->lease_fd = -1;
-       struct cmsghdr *cmsg;
-       for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
-            cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-               if (cmsg->cmsg_level == SOL_SOCKET &&
-                   cmsg->cmsg_type == SCM_RIGHTS) {
-                       int nfds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-                       int *fds = (int *)CMSG_DATA(cmsg);
-
-                       if (nfds == 1) {
-                               lease->lease_fd = fds[0];
-                               break;
-                       }
-
-                       DEBUG_LOG(
-                           "Expected 1 fd from lease manager. Received %d\n",
-                           nfds);
-                       /* Close any unexpected fds so we don't leak them. */
-                       for (int i = 0; i < nfds; i++)
-                               close(fds[i]);
-                       break;
-               }
-       }
+       return true;
 
-       if (lease->lease_fd < 0) {
-               DEBUG_LOG("Expected data not received from lease manager\n");
-               errno = EPROTO;
-               return false;
+err:
+       switch (errno) {
+       case EACCES:
+               DEBUG_LOG("Lease request rejected by DRM lease manager\n");
+               break;
+       case EPROTO:
+               DEBUG_LOG("Unexpected data received from lease manager\n");
+               break;
+       default:
+               DEBUG_LOG("Lease manager receive data error: %s\n",
+                         strerror(errno));
+               break;
        }
-
-       return true;
+       return false;
 }
 
 struct dlm_lease *dlm_get_lease(const char *name)
@@ -159,7 +120,7 @@ struct dlm_lease *dlm_get_lease(const char *name)
        }
 
        if (!lease_send_request(lease, DLM_GET_LEASE))
-               goto err;
+               goto err_request;
 
        if (!lease_recv_fd(lease))
                goto err;
@@ -168,8 +129,11 @@ struct dlm_lease *dlm_get_lease(const char *name)
 
 err:
        saved_errno = errno;
-       dlm_release_lease(lease);
+       lease_send_request(lease, DLM_RELEASE_LEASE);
        errno = saved_errno;
+err_request:
+       close(lease->dlm_server_sock);
+       free(lease);
        return NULL;
 }