<html>
    <head>
      <base href="https://bugs.llvm.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 - common glob interceptor doesn't handle GLOB_DOFFS correctly"
   href="https://bugs.llvm.org/show_bug.cgi?id=40822">40822</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>common glob interceptor doesn't handle GLOB_DOFFS correctly
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>6.0
          </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>asan
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>adembo@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>It looks like unpoison_glob_t doesn't properly account for GLOB_DOOFFS when
iterating over the glob results. By not adding pglob->gl_offs to the iteration
index, it ends up calling strlen on a null pointer.

Here's what the manpage for glob has to say about GLOB_DOOFFS:

       GLOB_DOOFFS
              Reserve pglob->gl_offs slots at the beginning of the list of
strings in pglob->pathv.  The reserved slots contain null pointers.

I found this while trying to reproduce an old memory leak in libgssapi-krb5
(<a href="http://krbdev.mit.edu/rt/Ticket/Display.html?id=7981">http://krbdev.mit.edu/rt/Ticket/Display.html?id=7981</a>). At one time, the
library called glob with GLOB_DOOFFS (it doesn't any more).


$ cat test.c
#include <fcntl.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
  int fd = creat("foo", S_IRWXU | S_IRWXG | S_IRWXO);
  if (fd == -1) {
    perror("creat");
    return 1;
  }
  int rc = close(fd);
  if (rc) {
    perror("close");
    return rc;
  }
  glob_t globbuf;
  memset(&globbuf, 0, sizeof(globbuf));
  int flags = 0;
#ifdef TEST_DOOFFS
  globbuf.gl_offs = 1;
  flags |= GLOB_DOOFFS;
#endif
  rc = glob("foo", flags, NULL, &globbuf);
  if (rc) {
    perror("glob");
    globfree(&globbuf);
    return rc;
  }
  for (int i = 0; i < globbuf.gl_pathc; i++) {
    int index = i;
#ifdef TEST_DOOFFS
    index += globbuf.gl_offs;
#endif
    printf("%s\n", globbuf.gl_pathv[index]);
  }
  globfree(&globbuf);
  return 0;
}

$ clang -g -o test test.c && ./test
foo
$ clang -g -o test -DTEST_DOOFFS=1 test.c && ./test
foo
$ clang -fsanitize=address -g -o test test.c && ./test
foo
$ clang -fsanitize=address -g -o test -DTEST_DOOFFS=1 test.c && ./test
AddressSanitizer:DEADLYSIGNAL
=================================================================
==28548==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc
0x7f39228a85a1 bp 0x7ffc5b5f9110 sp 0x7ffc5b5f8888 T0)
==28548==The signal is caused by a READ memory access.
==28548==Hint: address points to the zero page.
    #0 0x7f39228a85a0 
/build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/multiarch/strlen-avx2.S:59
    #1 0x45d83b in unpoison_glob_t(void*, __sanitizer::__sanitizer_glob_t*)
(/tmp/test+0x45d83b)
    #2 0x45e3d2 in glob (/tmp/test+0x45e3d2)
    #3 0x512422 in main /tmp/test.c:28:8
    #4 0x7f392273bb96 in __libc_start_main
/build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #5 0x419e29 in _start (/tmp/test+0x419e29)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV
/build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/multiarch/strlen-avx2.S:59 
==28548==ABORTING</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>