<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/55595>55595</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            MSan miss on O1 optimization level (for CVE-2016-20014)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            compiler-rt:asan,
            llvm:optimizations
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Teemperor
      </td>
    </tr>
</table>

<pre>
    *Note*: I'm aware that this is happening due to a (legal) optimization and this is not technically a bug in the optimizer (nor the sanitizer implementation really). This (and a few other bugs I'm filing) mostly serve as a basis for an upcoming RFC on how to fix these issues.

The code below is reading uninitialized memory but on -O1 (which is the msan recommended level) this uninitialized read (and the free call) gets optimized away before the MSan pass. Note that both GCC and Clang actually end up turning undef into 0 so free is never called (unless you're using O0 or another compiler).

```
#include <stdlib.h>

struct rep {
  int *x;
};

int main() {
  struct rep r;
  if (r.x)
    free(r.x);
}
```
https://godbolt.org/z/zP535rEzM

The code above is a 1-1 copy of CVE-2016-20014 but I found the same bug in a bunch of libraries and applications (WINE, X11, Bullet, some file system drivers, etc.).

Some more info about what happens:

SROA replaces the access with an `undef` and the last time we see the `undef` is before IPSCC (see the optimizer log below):

```llvm
*** IR Dump After EarlyCSEPass on main ***
; Function Attrs: mustprogress norecurse nounwind sspstrong uwtable
define dso_local i32 @main() #0 {
  br i1 undef, label %1, label %2

1:                                                ; preds = %0
  br label %2

2:                                                ; preds = %1, %0
  ret i32 0
}
*** IR Dump After IPSCCPPass on [module] ***
; Function Attrs: mustprogress norecurse nounwind sspstrong uwtable
define dso_local i32 @main() #0 {
  br label %1

1:                                                ; preds = %0
  ret i32 0
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVl1P4zgU_TXpi9UqH4TShz6Utqx4mAEBmt23lZPctF45cWQ7lPLr91ynhYCYh5VmpEUhaZ37dc49125hquMySlffjSc8omwlbqN03gh5kJaE30uPm3IC1152HbWq3YmqxysjpIjSK007qaN0IUznVaNepVemFbKt3vxagxhU7ltVSq2PcCv6nVAtDOjsRZZjtcaGRSdb5cOiajpNDbV-CGuJIyDbTDxxdPhwJilqOggDV8ux3QlDrTSq5doa4zwyO7LPJKTjEqSDf42EshV9V5qGgT3crAXS7M2B8dXqhctxBBSuJzeL4k0Ur4b7E-osTUWiIA1zBENxFQfpwRHKlxoIKtFQY-wRZXmOPL1LuOjDXpV79mG0DeDCGSUAaAUXTc8UKA0MfgzHSc6w2bm2hDrACtvvyLs3RivuIRITQFKw_faIRJ10bia430N3C9Am_livQ8vWWgKALH0fOoVywI3wvW0HYBXVaByoiYUzQ25uMOq1oQgKtfWtJufE0fRoA3L3jr3vYhHYHtoEtJ3SZLmXY1qjy_h0DV_TTLWl7sFzlK2dr7QqZvso2459nLd96UFNJ6L59bAmuE4Us3qJstNSNN-8fw53NmmkalEz0zdyHoW0b06IWTM-O3uB-XlNBB7el8fpvoK0975zGLQovcG1M1VhtJ8ZC6HevPL_fZ7ldvv67Uu1ycI8B9KlSKYJ1rqjMLVY_9hO0zi5xC1OLoLabqHu_qQSJxs6Tx2PXwv1wQtkWmkVudB8jLfGiPKghcn68_b7NkrX4q8k4cd1j_56_uQMomG4EPfoPDWisgoKcPyOfDn73NNHtm9YhaqtDUNAeQcW37ClBDbG9g93K6Zey5KGEZFlyYo6KGgVGgaXQYt4ivMgaOmwzShkOqAuGhQ_NgRnp1m4vX-E3oHwbPa-CWmzGwY6dHL1pTK1fm7O6jxd4vZBbPqmE6vaI8pWWn1cP27vMWs89awx8WZ88s2uxQ0aEfa1lfeWWRBN73xnzc4yXGyHVPYW-0-LTh4UkDrXQZqGh_HgZaFpCAaIqiVROfO3NhhEobJURBfxWNxpFo8VXmBzTYaR5r5pCdgwypMP39IxAwlX-B__GGZnqYKisg1HjEcFfJ0m_RVpAoxxOks-sBJ_ns6f9DCI5P7cwSi_bkzVg-988z_s5Kh7v61fPyXwPBeTaplVi2whJ155Tctw3DRqIBDn3ocfCOGM4xnkI_jj7gWMk97q5aeNErPfFzOcG_gSRnB4TEHyP1RiY7oZTml8yPN8kU_2y0Vcl0l1VS_qOq2StChpUVcXcXZJSVrO5-kk8OaW6G6UpucjaWo9skqcylgcZJSGhNlqDMHx23wzUcs0TtM4TxbJ_CLJ57OaiuyqvEjmeFwuZIzuEdqnZxyEN_qJXYbK-acKXmrlvHt_CcWpXUsUqkJ82fu9scsnoqYja-wkwFwGjP8C-6ntsw">