Example #1
0
int main() {
    int pid;
    int fds[3];
    int spair[2];

    sys_chk(socketpair(AF_UNIX, SOCK_STREAM, 0, spair));

    sys_chk(pid = fork());
    if (pid == 0) {  // Child.
        sys_chk(fds[0] = open("/etc/passwd", O_RDONLY));
        sys_chk(lseek(fds[0], 5, SEEK_SET));
        sys_chk(fds[1] = open("/etc/group", O_RDONLY));
        sys_chk(lseek(fds[1], 10, SEEK_SET));
        sys_chk(fds[2] = open("/bin/sh", O_RDONLY));
        sys_chk(lseek(fds[2], 20, SEEK_SET));
        send_fds(spair[0], fds, 3);
        return EXIT_SUCCESS;
    } else {  // Parent.
        int *fds;
        int fds_len;
        recv_fds(spair[1], &fds, &fds_len);
        printf("parent: got fds:");
        for (int i = 0; i < fds_len; ++i) {
            printf(" %d (fp=%lld)", fds[i], (long long)lseek(fds[i], 0, SEEK_CUR));
        }
        printf("\n");
        return EXIT_SUCCESS;
    }
}
Example #2
0
int parasite_drain_fds_seized(struct parasite_ctl *ctl,
		struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts)
{
	int ret = -1, size;
	struct parasite_drain_fd *args;

	size = drain_fds_size(dfds);
	args = parasite_args_s(ctl, size);
	memcpy(args, dfds, size);

	ret = parasite_execute(PARASITE_CMD_DRAIN_FDS, ctl);
	if (ret) {
		pr_err("Parasite failed to drain descriptors\n");
		goto err;
	}

	ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, opts);
	if (ret) {
		pr_err("Can't retrieve FDs from socket\n");
		goto err;
	}

err:
	return ret;
}
Example #3
0
int do_recvmsg(message *dev_m_in, message *dev_m_out)
{
	int minor;
	int rc;
	struct msg_control msg_ctrl;
	socklen_t controllen_avail = 0;
	socklen_t controllen_needed = 0;
	socklen_t controllen_desired = 0;

#if DEBUG == 1
	static int call_count = 0;
	printf("(uds) [%d] do_sendmsg() call_count=%d\n",
					uds_minor(dev_m_in), ++call_count);
#endif

	minor = uds_minor(dev_m_in);


#if DEBUG == 1
	printf("(uds) [%d] CREDENTIALS {pid:%d,uid:%d,gid:%d}\n", minor,
				uds_fd_table[minor].ancillary_data.cred.pid,
				uds_fd_table[minor].ancillary_data.cred.uid,
				uds_fd_table[minor].ancillary_data.cred.gid);
#endif

	memset(&msg_ctrl, '\0', sizeof(struct msg_control));

	/* get the msg_control from the user, it will include the
	 * amount of space the user has allocated for control data.
	 */
	rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
					(vir_bytes) 0, (vir_bytes) &msg_ctrl,
					sizeof(struct msg_control));

	if (rc != OK) {
		return EIO;
	}

	controllen_avail = MIN(msg_ctrl.msg_controllen, MSG_CONTROL_MAX);

	if (uds_fd_table[minor].ancillary_data.nfiledes > 0) {
		controllen_needed = CMSG_LEN(sizeof(int) *
				(uds_fd_table[minor].ancillary_data.nfiledes));
	}

	/* if there is room we also include credentials */
	controllen_desired = controllen_needed +
				CMSG_LEN(sizeof(struct ucred));

	if (controllen_needed > controllen_avail) {
		return EOVERFLOW;
	}

	rc = recv_fds(minor, &uds_fd_table[minor].ancillary_data, &msg_ctrl);
	if (rc != OK) {
		return rc;
	}

	if (controllen_desired <= controllen_avail) {
		rc = recv_cred(minor, &uds_fd_table[minor].ancillary_data,
								&msg_ctrl);
		if (rc != OK) {
			return rc;
		}
	}

	/* send the user the control data */
	rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
		(vir_bytes) 0, (vir_bytes) &msg_ctrl,
		sizeof(struct msg_control));

	return rc ? EIO : OK;
}