netdev-dpdk: Do not add vhost-user ports with '/' or '\' in name.
authorDaniele Di Proietto <diproiettod@vmware.com>
Wed, 3 Feb 2016 01:24:32 +0000 (17:24 -0800)
committerDaniele Di Proietto <diproiettod@vmware.com>
Wed, 24 Feb 2016 02:34:37 +0000 (18:34 -0800)
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 <diproiettod@vmware.com>
Acked-by: Flavio Leitner <fbl@sysclose.org>
INSTALL.DPDK.md
lib/netdev-dpdk.c

index d2865c3..ca49106 100644 (file)
@@ -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`
 
index f94e0d4..71034a0 100644 (file)
@@ -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_);
     }