From 1af27e8a4e08ac993834bcbc8ef49ef6e50a9385 Mon Sep 17 00:00:00 2001 From: Daniele Di Proietto Date: Tue, 2 Feb 2016 17:24:32 -0800 Subject: [PATCH] netdev-dpdk: Do not add vhost-user ports with '/' or '\' in name. This check prevents an obvious way for a vhost-user socket to escape the intended directory. There might be other ways to escape the directory (none comes to mind at the moment), but this is a problem that should be properly solved by mandatory access control. A similar check is done for a bridge name, since that name is used as part of a socket as well. Signed-off-by: Daniele Di Proietto Acked-by: Flavio Leitner --- INSTALL.DPDK.md | 3 ++- lib/netdev-dpdk.c | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/INSTALL.DPDK.md b/INSTALL.DPDK.md index d2865c394..ca49106ce 100644 --- a/INSTALL.DPDK.md +++ b/INSTALL.DPDK.md @@ -511,7 +511,8 @@ Adding DPDK vhost-user ports to the Switch: Following the steps above to create a bridge, you can now add DPDK vhost-user as a port to the vswitch. Unlike DPDK ring ports, DPDK vhost-user ports can -have arbitrary names. +have arbitrary names, except that forward and backward slashes are prohibited +in the names. - For vhost-user, the name of the port type is `dpdkvhostuser` diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index f94e0d4b0..71034a0eb 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -683,14 +683,26 @@ static int netdev_dpdk_vhost_user_construct(struct netdev *netdev_) { struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_); + const char *name = netdev_->name; int err; + /* 'name' is appended to 'vhost_sock_dir' and used to create a socket in + * the file system. '/' or '\' would traverse directories, so they're not + * acceptable in 'name'. */ + if (strchr(name, '/') || strchr(name, '\\')) { + VLOG_ERR("\"%s\" is not a valid name for a vhost-user port. " + "A valid name must not include '/' or '\\'", + name); + return EINVAL; + } + ovs_mutex_lock(&dpdk_mutex); /* Take the name of the vhost-user port and append it to the location where * the socket is to be created, then register the socket. */ snprintf(netdev->vhost_id, sizeof(netdev->vhost_id), "%s/%s", - vhost_sock_dir, netdev_->name); + vhost_sock_dir, name); + err = rte_vhost_driver_register(netdev->vhost_id); if (err) { VLOG_ERR("vhost-user socket device setup failure for socket %s\n", @@ -698,7 +710,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev_) } else { fatal_signal_add_file_to_unlink(netdev->vhost_id); VLOG_INFO("Socket %s created for vhost-user port %s\n", - netdev->vhost_id, netdev_->name); + netdev->vhost_id, name); err = vhost_construct_helper(netdev_); } -- 2.20.1