<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - MemorySanitizer va arg helpers are broken if function has many parameters before vararg part."
   href="https://llvm.org/bugs/show_bug.cgi?id=27646">27646</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>MemorySanitizer va arg helpers are broken if function has many parameters before vararg part.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

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

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

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Miscellaneous Instrumentation passes
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>koriakin@0x04.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The x86_64 and aarch64 vararg helpers in memorysanitizer pass currently assume
no non-vararg argument ends up in the overflow area - if that's not true, the
data stored to __msan_va_arg_tls will be misaligned with the overflow pointer
computed by va_start.  Here's a testcase for x86_64:

#include <stdio.h>
#include <stdarg.h>

int passarg(int a, int b, int c, int d, int e, int f, int g, ...) {
        va_list v;
        va_start(v, g);
        int res = va_arg(v, int);
        va_end(v);
        return res;
}

int main() {
        int undef;
        int res = passarg(undef, undef, undef, undef, undef, undef, undef, 2);
        if (res)
                printf("%d\n", res);
        return 0;
}

Compiling with -fsanitize=memory and running results in:

==22438==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x4889ef in main (/home/mwk/llvm/llvm/a.out+0x4889ef)
    #1 0x7f78129fe70f in __libc_start_main (/usr/lib/libc.so.6+0x2070f)
    #2 0x418e38 in _start (/home/mwk/llvm/llvm/a.out+0x418e38)

This is because va_arg effectively reads the shadow belonging to argument g.

aarch64 should be suspectible to the same issue, but I haven't checked it.

mips64 is even worse, since it assumes there's exactly one non-vararg argument.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>