From patchwork Tue May 1 15:31:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 156145 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8AE6DB6FA9 for ; Wed, 2 May 2012 01:51:35 +1000 (EST) Received: from localhost ([::1]:35862 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPFMT-0000cl-Fw for incoming@patchwork.ozlabs.org; Tue, 01 May 2012 11:51:33 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45014) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPFMH-0000UA-Ao for qemu-devel@nongnu.org; Tue, 01 May 2012 11:51:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SPFMF-000092-2S for qemu-devel@nongnu.org; Tue, 01 May 2012 11:51:20 -0400 Received: from e06smtp17.uk.ibm.com ([195.75.94.113]:42865) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPF4Y-0001Bz-Kh for qemu-devel@nongnu.org; Tue, 01 May 2012 11:33:02 -0400 Received: from /spool/local by e06smtp17.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 1 May 2012 16:32:04 +0100 Received: from d06nrmr1806.portsmouth.uk.ibm.com (9.149.39.193) by e06smtp17.uk.ibm.com (192.168.101.147) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 1 May 2012 16:32:01 +0100 Received: from d06av08.portsmouth.uk.ibm.com (d06av08.portsmouth.uk.ibm.com [9.149.37.249]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q41FW1VU2814108 for ; Tue, 1 May 2012 16:32:01 +0100 Received: from d06av08.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q41FW0RM017527 for ; Tue, 1 May 2012 09:32:00 -0600 Received: from localhost (stefanha-thinkpad.manchester-maybrook.uk.ibm.com [9.174.219.241]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q41FW0oD017524; Tue, 1 May 2012 09:32:00 -0600 From: Stefan Hajnoczi To: Date: Tue, 1 May 2012 16:31:47 +0100 Message-Id: <1335886307-27586-6-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1335886307-27586-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1335886307-27586-1-git-send-email-stefanha@linux.vnet.ibm.com> x-cbid: 12050115-0542-0000-0000-000001BC91D2 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.113 Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , libvir-list@redhat.com, Corey Bryant Subject: [Qemu-devel] [RFC 5/5] Example -open-hook-fd server X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch implements a demo server for the new -open-hook-fd feature. It opens any filename given to it by QEMU and therefore adds no true security. But it serves as a good debugging tool to see what requests QEMU is making. $ gcc -o test-fd-passing -Wall test-fd-passing.c $ ./test-fd-passing path/to/my/vm.img Try: (qemu) change ide1-cd0 path/to/a/cdrom.iso Signed-off-by: Stefan Hajnoczi --- test-fd-passing.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 test-fd-passing.c diff --git a/test-fd-passing.c b/test-fd-passing.c new file mode 100644 index 0000000..43b2e86 --- /dev/null +++ b/test-fd-passing.c @@ -0,0 +1,147 @@ +/* + * QEMU -open-hook-fd test server + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Stefan Hajnoczi + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + * + * gcc -o test-fd-passing -Wall test-fd-passing.c + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + uint32_t message_len; + uint32_t type; + uint32_t flags; + uint32_t mode; + uint32_t filename_len; + uint8_t filename[0]; +} OpenRequest; + +typedef struct { + uint32_t message_len; + uint32_t type; + int32_t result; +} OpenResponse; + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + int fds[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) { + perror("socketpair"); + return EXIT_FAILURE; + } + + char *fdstr = NULL; + asprintf(&fdstr, "%d", fds[1]); + + char *drivestr = NULL; + asprintf(&drivestr, "file=%s,cache=none,if=virtio", argv[1]); + + char *child_argv[] = { + "qemu-system-x86_64", + "-enable-kvm", + "-m", "1024", + "-drive", drivestr, + "-open-hook-fd", fdstr, + NULL, + }; + + pid_t child_pid; + if (posix_spawn(&child_pid, "x86_64-softmmu/qemu-system-x86_64", + NULL, NULL, child_argv, environ) != 0) { + fprintf(stderr, "posix_spawn failed\n"); + return EXIT_FAILURE; + } + free(drivestr); + free(fdstr); + close(fds[1]); + + for (;;) { + OpenRequest req; + char filename[1024]; + + if (recv(fds[0], &req, sizeof(req), 0) != sizeof(req)) { + perror("recv"); + return EXIT_FAILURE; + } + + if (req.type != 1 /* OpenRequest */) { + fprintf(stderr, "Expected request type 1, got %u\n", req.type); + return EXIT_FAILURE; + } + + if (req.filename_len > sizeof(filename) - 1) { + fprintf(stderr, "Filename length too large (%u)\n", + req.filename_len); + return EXIT_FAILURE; + } + + if (recv(fds[0], filename, req.filename_len, 0) != req.filename_len) { + perror("recv"); + return EXIT_FAILURE; + } + filename[req.filename_len] = '\0'; + + fprintf(stderr, "open(\"%s\", %#x, %#o) = ", + filename, req.flags, req.mode); + + int fd, ret; + fd = ret = open(filename, req.flags, req.mode); + + fprintf(stderr, "%d (errno %d)\n", ret, errno); + + OpenResponse resp = { + .message_len = sizeof(resp), + .type = 1, + .result = ret < 0 ? -errno : 0, + }; + struct iovec iov = { + .iov_base = &resp, + .iov_len = sizeof(resp), + }; + char buf[CMSG_SPACE(sizeof(int))]; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + }; + if (ret >= 0) { + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + + 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), &fd, sizeof(fd)); + } + + ret = sendmsg(fds[0], &msg, 0); + if (ret < 0) { + perror("sendmsg"); + return EXIT_FAILURE; + } + close(fd); + } +}