File diff 8ea1abb31ecd → 1081bd358292
Show inline comments
@@ -176,13 +176,13 @@

  <dt>Can you explain further in words (rather than a picture) about the central
  component in ESXi that the lawsuit alleges violates the GPL?</dt>
    <p>The GPL violation at issue involves VMware's ESXi product.
    Conservancy independently reviewed ESXi 5.5 and its incomplete
    Conservancy independently reviewed ESXi and its incomplete
      <abbr title="complete, corresponding source">CCS</abbr>
    release as part of our GPL enforcement efforts described above.</p>

    <p>Conservancy's preliminary investigation indicated that the operating
    system kernel of VMware ESXi product consists of three key components:
@@ -240,27 +240,27 @@ Code, and for which (at least some) source code is provided.
       released <a href="#diagram">the diagram above</a> to exemplify that
       issue.  Conservancy continues to <a href="#court-documents">hope VMware will
       agree to make public all court documents</a> as a matter of public
       good, since the court documents discuss the specifics of alleged
         infringement on Hellwig's copyrights.</p>

       <p>However, Conservancy examined VMware's ESXi 5.5 product in detail
       <p>However, Conservancy examined VMware's ESXi product in detail
       even before Hellwig's enforcement action began.  Below is one example
       among many where VMware's CCS was incomplete per GPLv2&sect;2(c) and
       GPLv2&sect;3(a).  (One can verify these results by
       <a href="#verify">downloading and installing the binary and source
       packages for VMware's ESXi 5.5 Update 2</a>.)  Note that this
       packages for VMware's ESXi 6.0</a>.)  Note that this
       example below is not necessarily regarding
       Hellwig's copyrights; VMware incorporated Linux code copyrighted by
       many others as well into their kernel.</p>

       <h3>Example of &ldquo;vmkernel&rdquo;'s combination with Linux code</h3>
       <p>Our example begins with examination of the file
           called <code>vmkdrivers/src_92/vmklinux_92/vmware/linux_pci.c</code>,
           which can be found in the &ldquo;Open Source&rdquo; release for
           ESXi 5.5.0 Update 2 (5.5U2).  A small excerpt from that file, found in the
           ESXi 6.0.  A small excerpt from that file, found in the
           function <code>LinuxPCIDeviceRemoved()</code>, reads as follows:</p>

#include &lt;linux/pci.h&gt;
@@ -276,23 +276,23 @@ LinuxPCIDeviceRemoved(vmk_PCIDevice vmkDev)
  if (unlikely(
    vmk_PCIGetDeviceName(vmkDev, vmkDevName, sizeof(vmkDevName)-1) != VMK_OK))
      vmkDevName[0] = 0;

<h4>Combination of &ldquo;vmkernel&rdquo; code with &ldquo;vmkdrivers&rdquo;</h4>

<p>The function, <code>vmk_PCIGetDeviceName()</code> must be defined, with an
      implementation, for this code above to work, or even compile.
      Inside <code>BLD/build/HEADERS/vmkapi-current-all-public/vmkernel64/release/device/vmkapi_pci_incompat.h</code>,
      found in the <code>vmkdrivers</code> package of ESXi 5.5U2, shows a
      Inside <code>BLD/build/HEADERS/vmkapi-current-all-public/generic/release/hardware/vmkapi_pci_incompat.h</code>,
      found in the <code>vmkdrivers</code> package of ESXi 6.0, shows a
      function header definition for <code>vmk_PCIGetDeviceName()</code>.
      However, the source of its implementation is not provided there or
      anywhere in the source release.</p>

<p>Further evidence that the implementation of this function occurs elsewhere
  can by found by running <code>objdump -x</code> on the un-vmtar'ed
@@ -306,36 +306,36 @@ VMKAPI_MODULE_CALL_VOID(pciDevExt->moduleID,
&hellip;and the following lines found in the  &ldquo;RELOCATION RECORDS FOR
[.text]&rdquo; section:

00000000000327ff R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
0000000000035318 R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
00000000000387e1 R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
000000000003cf40 R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
0000000000032db3 R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
00000000000333ea R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
0000000000036644 R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc
000000000003986a R_X86_64_PC32     vmk_PCIGetDeviceName+0xfffffffffffffffc

<p>The above two properties both suggest that the <code>vmklinux_9</code>
 module requires: (a) a definition of the <code>vmk_PCIGetDeviceName()</code>
 function to operate, but (b) that function is not defined
 inside <code>vmklinux_9</code> itself.</p>

<p>The definition can however be found in binary-only software provided in
  ESXi 5.5U2 &mdash; specifically, inside a file named <code>k.b00</code>,
  ESXi 6.0 &mdash; specifically, inside a file named <code>k.b00</code>,
  which is located in partition 5 on a disk where ESXi has been installed (or
  in the ESXi 5.5U2 installer ISO image).  Running <code>file</code>
  in the ESXi 6.0 installer ISO image).  Running <code>file</code>
  after <code>gunzip</code> on this file yields &ldquo;ELF 64-bit LSB shared
  object&rdquo;.  Meanwhile, <code>file k.b00</code> reports &ldquo;gzip
  compressed data, was &lsquo;vmvisor64-vmkernel.stripped&rsquo;&rdquo;.
  These findings strongly suggests this is an image of the
  &ldquo;vmkernel&rdquo; component.  An <code>objdump -x</code> yields this
  &ldquo;SYMBOL TABLE&rdquo; section:</p>

000041800036a408 g     F .text  0000000000000137 vmk_PCIGetDeviceName
000041800033193c g     F .text  000000000000012e vmk_PCIGetDeviceName

<p>&hellip; which indicated these binary file contains the function body
for  <code>vmk_PCIGetDeviceName</code>.</p>

<p>Furthermore, after detailed searching, Conservancy found no evidence that any
@@ -355,42 +355,44 @@ for  <code>vmk_PCIGetDeviceName</code>.</p>
  A definition of <code>pci_dev</code> is found in
  <code>vmkdrivers/src_92/include/linux/pci.h</code> (which
  is <code>#include</code>'d above) reads:</p>

struct pci_dev {
#if defined(__VMKLNX__)
        /* 2008: Update from Linux source */
        u8              revision;       /* PCI revision, low byte of class word */
#endif /* defined(__VMKLNX__) */
       struct pci_driver *driver;      /* which driver has allocated this device */
truct pci_driver {
struct pci_driver {
        struct list_head node;
        char *name;
        void (*remove) (struct pci_dev *dev);   /* Device removed (NULL if not a hot-plug capable driver) */
#if defined(__VMKLNX__)
        /* 2008: Update from Linux source */
        u8              revision;       /* PCI revision, low byte of class word */
#endif /* defined(__VMKLNX__) */

<p>These structures, and based on those from Linux itself
  (<a href="">a
    similar version of this file can be seen in Linux 2.6.24</a>), and as can
  be seen above, have been modified to work with &ldquo;vmkernel&rdquo;</p>
  be seen above, have been modified to work with &ldquo;vmkernel&rdquo;.</p>

<p>In <code>LinuxPCIDeviceRemoved()</code>, we saw a macro called with a
  variable, <code>linuxDev</code> which was of type <code>struct pci</code>.
  Thus, the combination of code from Linux's <code>pci.h</code>
  and VMware's <code>vmware/linux_pci.c</code> is very tightly coupled and

<h4><code>VMKAPI_MODULE_CALL_VOID</code> macro calls driver's code</h4>

  file <code>BLD/build/HEADERS/vmkapi-current-all-public/vmkernel64/release/base/vmkapi_module.h</code>
  file <code>BLD/build/HEADERS/vmkapi-current-all-public/generic/release/base/vmkapi_module.h</code>
  contains the macro definition of  <code>VMKAPI_MODULE_CALL_VOID</code>,
  which is quoted below (with debug lines removed):
#define VMKAPI_MODULE_CALL_VOID(moduleID, function, args...)  \
do {                                                    \
    vmk_ModInfoStack modStack;                          \
@@ -399,14 +401,14 @@ do {                                                    \
    )                                                   \
    vmk_ModulePopId();                                  \
} while(0)

<p>When the macro is expanded, it means that <code>(function)(args)</code> is
  actually expanded to <code>linuxDev->driver->remove(linuxDev)</code>.
  Therefore, we see <code>LinuxPCIDeviceRemoved()</code>, makes directs calls
  actually expanded to <code>linuxDev-&gt;driver-&gt;remove(linuxDev)</code>.
  Therefore, we see <code>LinuxPCIDeviceRemoved()</code> makes directs calls
  to a driver's remove() function, by combining with Linux's <code>struct
  pci</code>, and by VMware's introduction of this new calling code.
  Conservancy has confirmed many drivers from Linux are incorporated via
  these mechanisms; one specific example is discussed next.</p>

<h4>Combination of the tg3 driver with &ldquo;vmkernel&rdquo;</h4>
@@ -420,29 +422,29 @@ do {                                                    \
static struct pci_driver tg3_driver = {
        .remove         = __devexit_p(tg3_remove_one),

<p>Therefore, when the code in <code>LinuxPCIDeviceRemoved()</code>
  calls <code>linuxDev->driver->remove(linuxDev)</code>, the code ultimately
  called (in the case where a tg3 card is driven by the kernel)
  calls <code>linuxDev-&gt;driver-&gt;remove(linuxDev)</code>, the code
  ultimately called (in the case where a tg3 card is driven by the kernel)
  is <code>tg3_remove_one()</code>, which is found in <code>tg3.c</code> and
  comes directly from Linux.</p>

<p>(Note: <code>__devexit_p</code> is a straightforward macro found
  in <code>vmkdrivers/src_92/include/linux/init.h</code> (which also comes
  from Linux) that will simply expand to its first argument in this

<h4>VMware distribution of binary version of <code>tg3.c</code></h4>

<p>VMware furthermore distributes a modified version of <code>tg.c</code> in
<p>VMware furthermore distributes a modified version of <code>tg3.c</code> in
  binary form.  This can be found in <code>usr/lib/vmware/vmkmod/tg3</code>,
  which is extracted by un-vmtar'ing the file <code>net_tg3.v00</code> (found
  on the ESXi 5.5U2 installer ISO image).  Conservancy has confirmed that
  file is a compiled version of <code>tg3.c</code></p>
  on the ESXi 6.0 installer ISO image).  Conservancy has confirmed that
  file is a compiled version of <code>tg3.c</code>.</p>


<p>Given this evidence and related contextual clues, the only logical
  conclusions are:</p>
    <ul><li><code>vmklinux_9</code>, a binary object, dynamically links with
@@ -469,13 +471,14 @@ static struct pci_driver tg3_driver = {
      <li>Therefore, VMware failed to comply with the GPLv2, as such
      compliance requires source code (or an offer therefor) for the material
        in <code>k.b00</code>.</li>
<p>The above is but one piece of evidence among many, but hopefully it helps
  to explain some of the &ldquo;combined work&rdquo; violations found in
  VMware's ESXi product.</p>
  VMware's ESXi product.  Conservancy did a similar analysis for ESXi 5.0
  as well as ESXi 5.5 Update 2 and found nearly identical results.</p>

<dt id="verify">How can I verify Conservancy's technical findings above?</dt>

<dd><p>The binary and source packages mentioned above are available
on VMware's website.  These packages contain the
previously-mentioned <code>linux_pci.c</code>,
@@ -487,67 +490,67 @@ previously-mentioned <code>linux_pci.c</code>,
  repository that we built that includes the source components that VMware
  released</a>, and which are discussed above in our examples.  However, one
  can also obtain the source components directly from VMware, by following
  these steps (no login is required):</p>

<li>Visit <a href=""></a>.</li>
<li>Visit <a href=""></a>.</li>

<li>Click the &ldquo;Download&rdquo; button beside the text that reads
&ldquo;Open Source Code for VMware vSphere ESXi 5.5 Update 2&rdquo;.</li>
&ldquo;Open source software accompanying ESXi&rdquo;.</li>

<li>Confirm that the SHA-1 hash matches the published one
  (d121634668a137ec808b63679fd941cef9a59715), found under &ldquo;Read
  (35811b981470abe8b606d8a7a97c9795ce570597), found under &ldquo;Read
  More&rdquo; on that web page.</li>

<li>Mount (or otherwise open) the
  downloaded <code>VMware-ESX-550U2-ODP.iso</code>.</li>
  downloaded <code>VMware-ESXI-600-ODP.iso</code>.</li>

<li>Extract <code>vmkdrivers/src_92/vmklinux_92/vmware/linux_pci.c</code>
  and <code>BLD/build/HEADERS/vmkapi-current-all-public/vmkernel64/release/device/vmkapi_pci_incompat.h</code>
  and <code>BLD/build/HEADERS/vmkapi-current-all-public/generic/release/hardware/vmkapi_pci_incompat.h</code>
  from <code>vmkdrivers-gpl/vmkdrivers-gpl.tgz</code> with tar and gzip.</li>

<li>Generate <code>vmklinux_9</code> by following the steps
  in <code>vmkdrivers-gpl/BUILD.txt</code> in the ISO.
  (Note: <code>vmklinux_9</code> is also available pre-built on a running
  ESXi system; <a href="#vmklinux">see below for instructions on how to access it</a>).</li>

<li>You may need the &ldquo;Supporting Toolchain packages for VMware
  vSphere ESXi 5.5.0 Update 2&rdquo; file from the above download page to
<li>You may need the &ldquo;Open source software disclosure package for
  toolchain&rdquo; file from the above download page to
  complete the build &mdash; upon downloading you will find it is named
  <code>VMware-TOOLCHAIN-550u2-ODP.iso</code> and has a SHA-1 hash of
  <code>VMware-TOOLCHAIN-600-ODP.iso</code> and has a SHA-1 hash of


  <p>To obtain the binary components, follow these steps (a login is required):<p>

<li>Register for an account at <a href=""></a>.</li>

<li>Click the &ldquo;Activate Now&rdquo; link in the follow-up email.  Enter
  the password used at registration time.  Click &ldquo;Continue&rdquo;.</li>

<li>Visit <a href=""></a>.</li>
<li>Visit <a href=""></a>.</li>

<li>Click &ldquo;Register&rdquo; (under the text that reads &ldquo;You have
  not registered for this product&rdquo;).</li>

<li>Enter the number of servers you plan to install on (e.g., 1).  Click

<li>If the &ldquo;VMware vSphere Hypervisor 5.5 Update 2 &ndash;
<li>If the &ldquo;VMware vSphere Hypervisor 6.0 &ndash;
  Binaries&rdquo; section is not expanded, click the plus sign next to it.</li>

<li>Click the &ldquo;Manually Download&rdquo; link that's beside &ldquo;ESXi
  5.5 Update 2 ISO image (Includes VMware Tools)&rdquo;.</li>
  ISO image (Includes VMware Tools)&rdquo;.</li>

<li>Confirm that the SHA-1 hash matches the published one (9475938b51cafc86c8b17d09f2493cb6b4fae927).</li>
<li>Confirm that the SHA-1 hash matches the published one (a38a9d37ea529329338de049679c1dd1687d3860).</li>

<li>Mount (or open via some other means) the
downloaded <code>VMware-VMvisor-Installer-5.5.0.update02-2068190.x86_64.iso</code>.</li>
downloaded <code>VMware-VMvisor-Installer-6.0.0-2494585.x86_64.iso</code>.</li>

<li>Find the <code>k.b00</code> file in the root directory.  Extract it
using <code>zcat k.b00 &gt; vmvisor64-vmkernel</code> (or a similar command).
Repeat the steps described above using <code>objdump -x

@@ -615,13 +618,13 @@ copied Christoph's code into their product.</dd>
        <li><a href="">GNOME Foundation</a></li>
        <li><a href="">Open Source Initiative</a></li>
        <li><a href="">The
            Samba Team</a></li>
        <li><a href="">The
        SWIG Project</a></li>
        <li><a href="">Dave Airlie, Linux Developer</a></li>
        <li><a href="">Dave Airlie, Linux Developer</a></li>
        <li><a href="">Matthew Garrett, Linux Developer</a></li>
        <li><a href="/news/2015/mar/05/vmware-lawsuit/#glikely">Grant Likely, Linux Kernel Engineer</a></li>
        <li><a href="">Michal Nazarewicz, Linux Developer</a></li>
        <li><a href="">Luis R. Rodriguez (aka mcgrof), Linux Developer</a></li>
        <li><a href="">Wolfram Sang, Linux Developer</a></li>
        <li><a href="">Josh