<html>
    <head>
      <base href="https://bugzilla.netfilter.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - vfork() in xtables.c can corrupt stack"
   href="https://bugzilla.netfilter.org/show_bug.cgi?id=982">982</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>vfork() in xtables.c can corrupt stack
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>iptables
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>1.4.x
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>x86_64
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>other
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P5
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>iptables-restore
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>netfilter-buglog@lists.netfilter.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dan.wilder@watchguard.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=451" name="attach_451" title="Move some code to avoid cautions in vfork man page">attachment 451</a> <a href="attachment.cgi?id=451&action=edit" title="Move some code to avoid cautions in vfork man page">[details]</a></span>
Move some code to avoid cautions in vfork man page

Running iptables-restore on an embedded platform containing no modprobe
program, the following lines in xtables.c lead to corrupted stack frame:

 357     switch (vfork()) {
 358     case 0:
 359         argv[0] = (char *)modprobe;
 360         argv[1] = (char *)modname;
 361         if (quiet) {
 362             argv[2] = "-q";
 363             argv[3] = NULL;
 364         } else {
 365             argv[2] = NULL;
 366             argv[3] = NULL;
 367         }
 368         execv(argv[0], argv);
 369 
 370         /* not usually reached */
 371         exit(1);

modprobe pointed to a non-existant program /sbin/modprobe, so execv()
always failed.  Not a problem in itself on our platform, as the kernel
modules are pre-loaded before iptables-restore is run, but it took a 
bit of headscratching to track this down, as a stack frame was
corrupted, leading to failures quite a while after the function 
containing this code had returned!

Relevant caution in man 2 vfork:

    "The vfork() function has the same effect as fork(2), except that
    the behavior is undefined if the process created by vfork() either
    modifies any data ... or calls any other function before 
    successfully calling _exit(2) or one of the exec(3) family of  
    functions."

Apparently this has not been a problem for us in earlier versions of
glibc, maybe because vfork was more like fork, maybe because the
stack corruption was innocuous.  Ours is a corner case anyway, as
it might not have been a problem had modprobe existed or had 
modprobe been a symlink to /bin/true.  But it seems odd to disregard
man page cautions, and our problem goes away if they are heeded.

Our solution was move the argv setting up a few lines, just before the
vfork, and replace exit() with _exit().  The code reviewer suggested 
contributing the patch upstream, so please find attached, for 
whatever it may be worth.

--
Dan Wilder</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are watching all bug changes.</li>
      </ul>
    </body>
</html>