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

    <tr>
        <th>Summary</th>
        <td>
            memsan doesn't handle getdirentries()
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    It seems memsan doesn't mark the buffer which getdirentries() returns results in as initialised.

I can reproduce this with the clang-15 package in Debian experimental which is a recent snapshot:

```
Debian clang version 15.0.0-++20220309105819+8bef17ed59aa-1~exp1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```

Reproducer:

```
$ cat getdirentriestest.c 
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

int main() {
    off_t base = 0;
    char buf[1024];
    int dir = open("/proc/self/fd", O_RDONLY|O_DIRECTORY);
    if (dir < 0) return 1;
    errno = 0;
    ssize_t c = getdirentries(dir, buf, sizeof(buf), &base);
    if (c < 0) return 2;
    ssize_t pos = 0;
    while (pos < c) {
        struct dirent *d = (struct dirent *)(buf + pos);
        printf("%s\n", d->d_name);
        pos += d->d_reclen;
    }
    return 0;
}
$ clang-15 -Wall -W -g -fsanitize=memory getdirentriestest.c
$ ./a.out 
.
==1727340==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55bc49354aa0 in main /tmp/scratch/getdirentriestest.c:17:5
    #1 0x7fee76e047fc in __libc_start_main csu/../csu/libc-start.c:332:16
    #2 0x55bc492ce2c9 in _start (/tmp/scratch/a.out+0x212c9) (BuildId: c47086e0b8c95295b0012f67c32a50c9a129ae22)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /tmp/scratch/getdirentriestest.c:17:5 in main
Exiting
```

Line 17 is `while (pos < c) {` so memsan seems to understand `d->d_name` is initialised but not `d->d_reclen`.

(If you're wondering why use `getdirentries()` at all, POSIX doesn't currently require `readdir()` to be thread-safe.)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVVt1v4jgQ_2vCixXkOF_kgQcK7Qlp257aPe3tE3KcCfFucDjbaaF__Y4daGFLe1qEnDgz_s33jMuu2k-XlhiAjSEbXLgiVQdGBSy3ZMP1T2IbIGVf16DJcyNFQ9ZgK6lBWS3BBGwSsIJosL1WBp-mb60hUhHuVmklb6WBahzQRUBnw7okAuVo2Oqu6gWgCGnIs7SNFyZartZhlJItFz_5GhzYAkqJR2C3BS03KJu3B23wJEcogd-IUXxrms4G8exUXJDRw99vD1heDHkCbWSnSJSO6ZiGAbvCP6OM0ZgWEU0nUYEfJiXUUQ5VWnAeRkF-jYpEA9pXrtEhKJHsJtkqS8KtCFup-l24Vv2BpdHAK7LpKmgd47YzcnfwhDJoSgvVQmpHCthNbzSupVQXlR_Wh6Pr9OemBixBV9vzkFn8jwU5csRSibavgATxHLRW3bgJ4utLVIMgn1D3mAw3dr8F8z88aLL9kKUWyrYfUgcrTsl-lcolK7psyMYgvxq-E_x1db2ypOTGASwIDeITomi4dtkdpFcRZUmQLs7IDhdF-oPdFgZ8hiag-4WzBNoaH3Xlv87J_ephcX_35XuQz-9Xi-XD9fzr_cN3VOkctcY4TwbcOSr0Wj8kOuPz0bigtDHyBdAm4Wm_lyNunCrOKHw41g7fJn5fuE8By5w3Lmsl3unELsrGHL6gGZZkCw5mIM-JOAtHQAtjdS-8U13BBmxWeRg88o7i1XV64-bKCTzVGKG2GsNTH0OSmiCdq0McqhATpFopvoHfDznFsMhR5oEJe0eLkT01I8gXb5uDG94MfaX66jo2q_Ab1jGuJFyTsMY-iq3vBVAOdtVO7y-V4BvKGJOIj7veHqry2C1jTMdFlLM8Tuiw-TZ7uFve_eV6xa0HfjxI8u2jNxB2ddirY-d9gSp84m0PJ8axmBK6S9NSJEWcJpxT12Fd-bj2Yzdbl9hCcysafLukdzyLclzSM9AIQfMaIM-AJnktHOhq1cpSrLDgtV15CcL0CDp2Bg-vjiH0DB44jpmDz86g2au-TAAThYf2Z4gP_zulvS8xzHTHIuT3ScgmV71sq2XlHCWSnE5Q0XIiipQVaUlpxOosFzHjKRUFj1jBwSVTcdpnHv-5vZ1hQf-p9__UsceADFKvdwin1p_Mgy9SAYlyNwyR8nEVZpSY7jjnh6FvO9KrCqeg5apyp09rB_nl2RjHtmKJ6uwJ46F-Mno24lH6sib7DkOcayDPnZOBRmCL2DtHOYALFwknEecVlpIr47_vH5f_ntxHRK8de7vHovyvx6MOxc1W3_OO59Gi0t0pHCE0vAZMtmJUTeOqiAs-stK2MH1312nQfPTaBZ1GvW6njbVb44Ytu3Gxw7tKX45Ft3EZ3D4dHyHOhR8gMPVupDG9Q7hJk2KSj5ppXaVRIop8EuGXpCySqi5FVtc0zzNM63LU8hJaM8VRhF1MwTPxEK6jpYuRnPpLScIwUWkeZWOWCxHFFMosy0tW8SChgCnTjp0e406vR3rqVSr7tUEihs-aNyLHRr5WAF4c4vPeNp2edj-ey5GXO_V6_wJu_P1L">