]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: don't overwrite stack when getting ethtool gfeatures
authorLaine Stump <laine@laine.org>
Tue, 11 Aug 2015 17:45:46 +0000 (13:45 -0400)
committerCole Robinson <crobinso@redhat.com>
Tue, 22 Sep 2015 00:17:59 +0000 (20:17 -0400)
This fixes the crash described here:

 https://www.redhat.com/archives/libvir-list/2015-August/msg00162.html

In short, we were calling ioctl(SIOCETHTOOL) pointing to a too-short
object that was a local on the stack, resulting in the memory past the
end of the object being overwritten. This was because the struct used
by the ETHTOOL_GFEATURES command of SIOCETHTOOL ends with a 0-length
array, but we were telling ethtool that it could use 2 elements on the
array.

The fix is to allocate the necessary memory with VIR_ALLOC_VAR(),
including the extra length needed for a 2 element array at the end.

(cherry picked from commit bfaaa2b681018f3705bae17c001700a03f67d7c4)

src/util/virnetdev.c

index 1e20789b7bf16cc36ed4934667b4f5490e686637..c158ca3311c5b71654fd334d4a79d75607e4040c 100644 (file)
@@ -3130,7 +3130,7 @@ virNetDevGetFeatures(const char *ifname,
     size_t i = -1;
     struct ethtool_value cmd = { 0 };
 # if HAVE_DECL_ETHTOOL_GFEATURES
-    struct ethtool_gfeatures g_cmd = { 0 };
+    struct ethtool_gfeatures *g_cmd;
 # endif
     struct elem{
         const int cmd;
@@ -3188,10 +3188,14 @@ virNetDevGetFeatures(const char *ifname,
 # endif
 
 # if HAVE_DECL_ETHTOOL_GFEATURES
-    g_cmd.cmd = ETHTOOL_GFEATURES;
-    g_cmd.size = GFEATURES_SIZE;
-    if (virNetDevGFeatureAvailable(ifname, &g_cmd))
+    if (VIR_ALLOC_VAR(g_cmd,
+                      struct ethtool_get_features_block, GFEATURES_SIZE) < 0)
+        return -1;
+    g_cmd->cmd = ETHTOOL_GFEATURES;
+    g_cmd->size = GFEATURES_SIZE;
+    if (virNetDevGFeatureAvailable(ifname, g_cmd))
         ignore_value(virBitmapSetBit(*out, VIR_NET_DEV_FEAT_TXUDPTNL));
+    VIR_FREE(g_cmd);
 # endif
 
     if (virNetDevRDMAFeature(ifname, out) < 0)