[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 09/26] HACK: vhost-user-backend: allow to specify
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v3 09/26] HACK: vhost-user-backend: allow to specify binary to execute |
Date: |
Mon, 18 Jun 2018 18:17:12 +0200 |
An executable with its arguments may be given as 'cmd' property, ex:
-object vhost-user-backend,id=vui,cmd="./vhost-user-input
/dev/input..". The executable is then spawn and, by convention, the
vhost-user socket is passed as fd=3. It may be considered a security
breach to allow creating processes that may execute arbitrary
executables, so this may be restricted to some known executables (via
signature etc) or directory.
To make the patch more acceptable, the command argument would have to
be passed via an array (probably via -object json: syntax), instead of
using g_shell_parse_argv().
Signed-off-by: Marc-André Lureau <address@hidden>
---
backends/vhost-user.c | 83 +++++++++++++++++++++++++++++++++++++------
1 file changed, 73 insertions(+), 10 deletions(-)
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
index db97037306..32d3ec0e8b 100644
--- a/backends/vhost-user.c
+++ b/backends/vhost-user.c
@@ -154,26 +154,87 @@ vhost_user_backend_complete(UserCreatable *uc, Error
**errp)
{
VhostUserBackend *b = VHOST_USER_BACKEND(uc);
Chardev *chr;
+ char **argv = NULL;
- if (!b->chr_name) {
- error_setg(errp, "You must specificy 'chardev'.");
+ if (!!b->chr_name + !!b->cmd != 1) {
+ error_setg(errp, "You may specificy only one of 'chardev' or 'cmd'.");
return;
}
- chr = qemu_chr_find(b->chr_name);
- if (chr == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Chardev '%s' not found", b->chr_name);
- return;
- }
+ if (b->chr_name) {
+ chr = qemu_chr_find(b->chr_name);
+ if (chr == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Chardev '%s' not found", b->chr_name);
+ return;
+ }
- if (!qemu_chr_fe_init(&b->chr, chr, errp)) {
- return;
+ if (!qemu_chr_fe_init(&b->chr, chr, errp)) {
+ return;
+ }
+ } else {
+ QIOChannelCommand *child;
+ GError *err;
+ int sv[2];
+
+ if (!g_shell_parse_argv(b->cmd, NULL, &argv, &err)) {
+ error_setg(errp, "Fail to parse command: %s", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
+ error_setg_errno(errp, errno, "socketpair() failed");
+ goto end;
+ }
+
+ chr = CHARDEV(object_new(TYPE_CHARDEV_SOCKET));
+ if (!chr || qemu_chr_add_client(chr, sv[0]) == -1) {
+ error_setg(errp, "Failed to make socket chardev");
+ object_unref(OBJECT(chr));
+ goto end;
+ }
+
+ if (!qemu_chr_fe_init(&b->chr, chr, errp)) {
+ goto end;
+ }
+
+ child = qio_channel_command_new_spawn_with_pre_exec(
+ (const char * const *)argv, O_RDONLY | O_WRONLY,
+ pre_exec_cb, sv, errp);
+ if (!child) {
+ goto end;
+ }
+ b->child = QIO_CHANNEL(child);
+
+ close(sv[1]);
}
b->completed = true;
/* could vhost_dev_init() happen here, so early vhost-user message
* can be exchanged */
+end:
+ g_strfreev(argv);
+}
+
+static char *get_cmd(Object *obj, Error **errp)
+{
+ VhostUserBackend *b = VHOST_USER_BACKEND(obj);
+
+ return g_strdup(b->cmd);
+}
+
+static void set_cmd(Object *obj, const char *str, Error **errp)
+{
+ VhostUserBackend *b = VHOST_USER_BACKEND(obj);
+
+ if (b->child) {
+ error_setg(errp, "cannot change property value");
+ return;
+ }
+
+ g_free(b->cmd);
+ b->cmd = g_strdup(str);
}
static void set_chardev(Object *obj, const char *value, Error **errp)
@@ -202,6 +263,7 @@ static char *get_chardev(Object *obj, Error **errp)
static void vhost_user_backend_init(Object *obj)
{
+ object_property_add_str(obj, "cmd", get_cmd, set_cmd, NULL);
object_property_add_str(obj, "chardev", get_chardev, set_chardev, NULL);
}
@@ -210,6 +272,7 @@ static void vhost_user_backend_finalize(Object *obj)
VhostUserBackend *b = VHOST_USER_BACKEND(obj);
g_free(b->dev.vqs);
+ g_free(b->cmd);
g_free(b->chr_name);
vhost_user_cleanup(&b->vhost_user);
--
2.18.0.rc1
- Re: [Qemu-devel] [PATCH v3 02/26] chardev: remove qemu_chr_fe_write_all() counter, (continued)
- [Qemu-devel] [PATCH v3 01/26] chardev: avoid crash if no associated address, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 03/26] dmabuf: add y0_top, pass it to spice, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 04/26] vhost-user: simplify vhost_user_init/vhost_user_cleanup, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 05/26] libvhost-user: exit by default on VHOST_USER_NONE, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 06/26] vhost-user: wrap some read/write with retry handling, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 09/26] HACK: vhost-user-backend: allow to specify binary to execute,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v3 07/26] qio: add qio_channel_command_new_spawn_with_pre_exec(), Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 08/26] Add vhost-user-backend, Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 10/26] vhost-user: split vhost_user_read(), Marc-André Lureau, 2018/06/18
- [Qemu-devel] [PATCH v3 11/26] vhost-user: add vhost_user_input_get_config(), Marc-André Lureau, 2018/06/18