What's missing/wrong in these test programs?
Hi, I'm trying to write test programs for auth_user/server_authenticate (and later for proc_user/server_authenticate) and have problems to get them right. The attached programs generate the following output: ./auth_recv& ./auth_send auth_recv.c: Socket file descriptor = 3 auth_recv.c: Receiving via datagram socket auth_send.c: Socket file descriptor = 3 auth_send.c: Sending via datagram socket auth_send.c: rendezvous = 128 auth_send.c: mach_port_insert_right() err = 0 auth_send.c: Sent rendezvous port = 128 auth_send.c: send() returned 4 bytes auth_recv.c: recv() returned 4 bytes auth_recv.c: Received data = 128 auth_recv.c: rendezvous valid auth_recv.c: mach_port_mod_refs() err = 15 auth_recv.c: err = 15 EKERN_INVALID_NAME = 15 trying with mach_port_insert_right() gives error 18: EKERN_INVALID_VALUE = 18 What's missing/wrong here? Do I have to reauthenticate the received rendezvous port in auth_recv? /* test of auth_user/server authenticate: send part */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #define SOCK_PATH "auth_socket" int main (void) { mach_port_t rendezvous = NULL; mach_port_t newport; error_t err; int sfd; struct sockaddr_un addr = { 0 }; ssize_t ns; char wbuf[30]; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1); sfd = socket (AF_UNIX, SOCK_DGRAM, 0); if (sfd == -1) { perror ("socket"); exit(EXIT_FAILURE); } printf("auth_send.c: Socket file descriptor = %d\n", sfd); if (connect(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) { close(sfd); perror ("connect"); exit(EXIT_FAILURE); } printf("auth_send.c: Sending via datagram socket\n"); rendezvous = __mach_reply_port (); printf ("auth_send.c: rendezvous = %d\n", (int)rendezvous); err = mach_port_insert_right (mach_task_self (), rendezvous, rendezvous, MACH_MSG_TYPE_MAKE_SEND); printf ("auth_send.c: mach_port_insert_right() err = %d\n", err); if (err) goto out; sprintf(wbuf, "%d", (int)rendezvous); printf("auth_send.c: Sent rendezvous port = %d\n", (int)rendezvous); #if 0 ns = send(sfd, wbuf, 4, 0); #else err = HURD_DPORT_USE (sfd, __socket_send (port, MACH_PORT_NULL, 0, wbuf, 4, NULL, MACH_MSG_TYPE_COPY_SEND, 0, NULL, 0, &ns)); #endif if (ns == -1) { perror ("send"); exit(EXIT_FAILURE); } printf("auth_send.c: send() returned %ld bytes\n", (long) ns); // err = __USEPORT (AUTH, __auth_user_authenticate (port, // rendezvous, MACH_MSG_TYPE_COPY_SEND, err = __USEPORT (AUTH, auth_user_authenticate (port, rendezvous, MACH_MSG_TYPE_MAKE_SEND, &newport)); out: printf ("auth_send.c: newport=%d\n", (int)newport); __mach_port_deallocate (__mach_task_self (), rendezvous); __mach_port_deallocate (__mach_task_self (), newport); printf ("auth_send.c: err = %d\n", err); return err; } /* test of auth_user/server authenticate: recv part */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #define SOCK_PATH "auth_socket" int main (void) { __uid_t euids_buf[CMGROUP_MAX], auids_buf[CMGROUP_MAX]; __uid_t *euids = euids_buf, *auids = auids_buf; __gid_t egids_buf[CMGROUP_MAX], agids_buf[CMGROUP_MAX]; __gid_t *egids = egids_buf, *agids = agids_buf; size_t neuids = CMGROUP_MAX, nauids = CMGROUP_MAX; size_t negids = CMGROUP_MAX, nagids = CMGROUP_MAX; mach_port_t rendezvous; mach_port_t newport = MACH_PORT_NULL; error_t err; int sfd; struct sockaddr_un addr = { 0 }; ssize_t nr; char rbuf[30]; /* Create socket bound to well-known address */ err = remove (SOCK_PATH); if (err == -1 && errno != ENOENT) { perror ("remove"); exit(EXIT_FAILURE); } addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1); sfd = socket (AF_UNIX, SOCK_DGRAM, 0); if (sfd == -1) { perror ("socket"); exit(EXIT_FAILURE); } printf("auth_recv.c: Socket file descriptor = %d\n", sfd); err = bind (sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); if (err == -1) { close(sfd); perror ("bind"); exit(EXIT_FAILURE); } printf ("auth_recv.c: Receiving via datagram socket\n"); /* Receive data */ nr = recv (sfd, rbuf, 4, 0); if (nr == -1) { perror ("recv"); exit(EXIT_FAILURE); } printf("auth_recv.c: recv() returned %ld bytes\n", (long) nr); rendezvous = atoi (rbuf); if (nr > 0) printf("auth_recv.c: Received data = %d\n", (int)rendezvous); if (MACH_PORT_VALID (rendezvous)) printf ("auth_recv.c: rendezvous valid\n"); else printf ("auth_recv.c: rendezvous not valid\n"); err = mach_por
Re: boot hangs, corruption at every attempt
Hi, Justus Winter wrote: Use `show all tasks' then. >I do not want to spam the list, so I can send them if somebody finds >useful checking them. Don't send screenshots. If you must, copy the text. Use qemu's `-curses'. Since I have virtualbox, I cant copy the text, I did not find anything equivalent to a -curses option. show all tasks shows 44 process when the shutdown hangs. I attach two screenshots which show 43, the last one is /bin/sh They are just a few kb, but of course inconvenient to read, sorry. Does this help? can we know which process is hanging? Riccardo
Re: 'struct flock' has no member named 'l_end'
One last thing, in libpthread commit 8b48173fdc8f52a234ff9d3d1de5277c60d7eea4 the Makefile expects shm-directory.c to be present in sysdeps/generic/ but it is not. This file only exists in glibc 2.21 and is not yet implemented in our libpthread. Thanks you, Manolis
Re: What's missing/wrong in these test programs?
On Wed, 2015-04-08 at 10:12 +0200, Svante Signell wrote: > Hi, > > I'm trying to write test programs for auth_user/server_authenticate (and > later for proc_user/server_authenticate) and have problems to get them > right. The attached programs generate the following output: > ./auth_recv& > ./auth_send New try, now with sendmsg/recvmsg. Results Terminal 1: ./auth_recvmsg auth_recv.c: Socket file descriptor = 3 auth_recv.c: Receiving via datagram socket auth_recv.c: msgh.msg_controllen = 16 auth_recv.c: recvmsg() returned 4 auth_recv.c: Received data = 125 auth_recv.c: cmhp->cmsg_len[0] = 16 auth_recv.c: Received file descriptor = 4 auth_recv.c: rendezvous valid Terminal 2: ./auth_sendmsg auth_send.c: rendezvous port = 125 auth_send.c: Socket file descriptor = 3 auth_send.c: mach_port_insert_right() err = 0 auth_send.c: Sent data = 125 auth_send.c: msgh.msg_controllen = 16 auth_send.c: Sent file descriptor: sfd = 3 auth_send.c: cmhp->cmsg_len = 16 auth_send.c: Sending via datagram socket auth_send.c: sendmsg() returned 4 bytes Questions: How to send the rendzevous port: as real data or ancillary data? Should I use the received FD to do what?? The socket is already there. Using a named connection, i.e. filling in msgh.msg_name and msgh.msg_namelen? /* test of auth_user/server authenticate: send part */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #define SOCK_PATH "auth_socket" int main (void) { mach_port_t rendezvous = __mach_reply_port (); mach_port_t newport; error_t err; struct msghdr msgh; struct iovec iov; int sfd, data; struct sockaddr_un addr = { 0 }; ssize_t ns; //char wbuf[30]; int cspc = CMSG_SPACE(sizeof(int)); union { struct cmsghdr cmh; char control[cspc]; } control_un; struct cmsghdr *cmhp = NULL; printf ("auth_send.c: rendezvous port = %d\n", (int)rendezvous); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1); sfd = socket (AF_UNIX, SOCK_DGRAM, 0); if (sfd == -1) { perror ("socket"); exit(EXIT_FAILURE); } printf("auth_send.c: Socket file descriptor = %d\n", sfd); err = connect (sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); if (err == -1) { close(sfd); perror ("connect"); exit(EXIT_FAILURE); } err = mach_port_insert_right (mach_task_self (), rendezvous, rendezvous, MACH_MSG_TYPE_MAKE_SEND); printf ("auth_send.c: mach_port_insert_right() err = %d\n", err); if (err) goto out; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; data = rendezvous; iov.iov_base = &data; iov.iov_len = sizeof(int); printf("auth_send.c: Sent data = %d\n", data); msgh.msg_name = NULL; msgh.msg_namelen = 0; msgh.msg_control = control_un.control; msgh.msg_controllen = sizeof(control_un.control); printf("auth_send.c: msgh.msg_controllen = %d\n", (int)msgh.msg_controllen); cmhp = CMSG_FIRSTHDR(&msgh); cmhp->cmsg_len = CMSG_LEN(sizeof(int)); cmhp->cmsg_level = SOL_SOCKET; cmhp->cmsg_type = SCM_RIGHTS; *((int *) CMSG_DATA(cmhp)) = sfd; printf("auth_send.c: Sent file descriptor: sfd = %d\n", sfd); printf("auth_send.c: cmhp->cmsg_len = %d\n", (int)cmhp->cmsg_len); printf("auth_send.c: Sending via datagram socket\n"); ns = sendmsg(sfd, &msgh, 0); if (ns == -1) { perror ("sendmsg"); exit(EXIT_FAILURE); } printf("auth_send.c: sendmsg() returned %ld bytes\n", (long) ns); err = __USEPORT (AUTH, auth_user_authenticate (port, rendezvous, MACH_MSG_TYPE_MAKE_SEND, &newport)); out: printf ("auth_send.c: newport=%d\n", (int)newport); __mach_port_deallocate (__mach_task_self (), rendezvous); __mach_port_deallocate (__mach_task_self (), newport); if (err) { printf ("auth_send.c: err = %d\n", err); exit(EXIT_FAILURE); } else exit(EXIT_SUCCESS); } /* test of auth_user/server authenticate: recv part */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #define SOCK_PATH "auth_socket" int main (void) { __uid_t euids_buf[CMGROUP_MAX], auids_buf[CMGROUP_MAX]; __uid_t *euids = euids_buf, *auids = auids_buf; __gid_t egids_buf[CMGROUP_MAX], agids_buf[CMGROUP_MAX]; __gid_t *egids = egids_buf, *agids = agids_buf; size_t neuids = CMGROUP_MAX, nauids = CMGROUP_MAX; size_t negids = CMGROUP_MAX, nagids = CMGROUP_MAX; mach_port_t rendezvous; mach_port_t newport = MACH_PORT_NULL; error_t err; struct msghdr msgh; struct iovec iov; int sfd, data; struct sockaddr_un addr = { 0 }; ssize_t nr; //char rbuf[30]; int cspc = CMSG_SPACE(sizeof(int)); union { struct cmsghdr cmh; char control[cspc]; } control_un; struct cmsghdr *cmhp = NULL; /* Create socket bound to well-known addre
Re: boot hangs, corruption at every attempt
Hi Riccardo Mottola wrote: They are just a few kb, but of course inconvenient to read, sorry. Does this help? can we know which process is hanging? I forgot to mention that I have frozen the virtual machine in the kernel debugger, so I could in case resume it and ive more information. Riccardo
Re: 'struct flock' has no member named 'l_end'
Manolis Ragkousis, le Wed 08 Apr 2015 22:21:42 +0300, a écrit : > in libpthread commit > 8b48173fdc8f52a234ff9d3d1de5277c60d7eea4 the > Makefile expects shm-directory.c to be present in > sysdeps/generic/ but it is not. > > This file only exists in glibc 2.21 and is not yet > implemented in our libpthread. This is a 2.21 thing indeed. We'll just use the generic one, that's why we don't need to implement our own. So either we manage to make the addition libpthread-routines dependent on the libc version, or we just move on to 2.21 :) Samuel
Re: What's missing/wrong in these test programs?
Svante Signell, le Wed 08 Apr 2015 21:56:36 +0200, a écrit : > New try, now with sendmsg/recvmsg. Ah, I hadn't read your source code when answering on IRC. > How to send the rendzevous port: as real data or ancillary data? None of those two: real data wouldn't actually transfer the port, and as anciliary data, it would need to be an FD, which it isn't. What you want to do is not use the posix layer (send/sendmsg), but the underlying hurdish interface (which is what you'll want to use for running proc_identify for flock and SCM_CRED anyway), i.e. socket_send and socket_receive on the underlying port behind the socket FD. Those function will take and give the rendez-vous port properly (i.e. not just the port name value, but the real port transferred from one process to another, with most probably a different port name value in the target process). Samuel