Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exchanging SCM_CREDENTIALS with SCM_RIGHTS #1326

Closed
therealkenc opened this issue Nov 6, 2016 · 7 comments
Closed

Exchanging SCM_CREDENTIALS with SCM_RIGHTS #1326

therealkenc opened this issue Nov 6, 2016 · 7 comments
Labels

Comments

@therealkenc
Copy link
Collaborator

therealkenc commented Nov 6, 2016

Closing #706 which appears resolved and opening this to avoid confusion. Took a bit to track this because there aren't actually any syscall fails in 14959 (∴ no strace included). The test case below should output something like:

got pid: 13117
got fd: 5
got message buffer: hello

WSL gets the fd but not the pid. Apologies for the length of the test case. [I've always just assumed the Berkeley guys were high when they invented the socket API.]

/** scm-cred.cc 
 **/

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>

int main(int argc, const char* argv[]) {
  int sock_pair[2];
  if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sock_pair) < 0) {
    perror("socketpair: ");
    return -1;
  }

  int reader_fd = sock_pair[0];
  int writer_fd = sock_pair[1];

  int enable = 1;
  if (setsockopt(reader_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) < 0) {
    perror("setsockopt: ");
    return -1;
  }

  char buf[] = "hello";
  const size_t length = sizeof(buf);
  struct iovec iov = { buf, length };
  struct msghdr msg = {};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;  
  const ssize_t control_len_snd = CMSG_SPACE(sizeof(int));
  char control_buf_snd[control_len_snd];
  msg.msg_control = control_buf_snd;
  msg.msg_controllen = control_len_snd;
  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  memcpy(CMSG_DATA(cmsg), &reader_fd, sizeof(int));      
  if (sendmsg(writer_fd, &msg, 0) < 0) {
    perror("sendmesg: ");
    return -1;
  }

  char recv_buf[sizeof(buf)] = {};
  struct iovec iov2 = { recv_buf, length };
  msg.msg_iov = &iov2;
  msg.msg_iovlen = 1;
  const ssize_t control_len_rcv = CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int));
  char control_buf_rcv[control_len_rcv];
  msg.msg_control = control_buf_rcv;
  msg.msg_controllen = control_len_rcv;
  if (recvmsg(reader_fd, &msg, 0) < 0) {
    perror("recvmesg: ");
    return -1;
  }

  int got_fd = -1;
  pid_t got_pid = -1;
  if (msg.msg_controllen > 0) {
    struct cmsghdr* cmsg; // hides
    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
      const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
      if (cmsg->cmsg_level == SOL_SOCKET &&
          cmsg->cmsg_type == SCM_RIGHTS) {
        if (payload_len != sizeof(int)) {
          fprintf(stderr, "expected fd payload sizeof(int)\n");
          return -1;
        }
        got_fd = *reinterpret_cast<int*>(CMSG_DATA(cmsg));
        printf("got fd: %d\n", got_fd);
      }
      if (cmsg->cmsg_level == SOL_SOCKET &&
          cmsg->cmsg_type == SCM_CREDENTIALS) {
        if (payload_len != sizeof(struct ucred)) {
          fprintf(stderr, "expected rights payload sizeof(struct ucred)\n");
          return -1;
        }
        got_pid = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg))->pid;
        printf("got pid: %d\n", got_pid);
      }
    }
  }

  printf("got message buffer: %s\n", recv_buf);
  return 0;
}
@sunilmut
Copy link
Member

sunilmut commented Feb 1, 2017

Just an update that the fix for this has been checked in the dev branch and should soon hit the release branch. Please keep the feedback coming. Thanks @therealkenc for all the help with troubleshooting. Really helpful.

@therealkenc
Copy link
Collaborator Author

Test case passes in 15042. 💯

@sunilmut
Copy link
Member

sunilmut commented Mar 1, 2017

@therealkenc - Thanks for the validation.

@therealkenc
Copy link
Collaborator Author

Note this never made it into the 15042 release notes (to the extent it matters). I mention it only because there are a number of other fixinbound tags since 15031 (Feb 8th) that might be closed too.

@bbhoss
Copy link

bbhoss commented Mar 1, 2017

Can we expect this will make it in the creators update, or will we need to be on insider builds?

@benhillis
Copy link
Member

@bbhoss - everything that is currently in insider builds will be released in the Creator's update, so yes.

@sunilmut
Copy link
Member

sunilmut commented Mar 1, 2017

@therealkenc - I have updated the release notes around this. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants