[llvm-bugs] [Bug 40822] New: common glob interceptor doesn't handle GLOB_DOFFS correctly

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Feb 22 10:19:52 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=40822

            Bug ID: 40822
           Summary: common glob interceptor doesn't handle GLOB_DOFFS
                    correctly
           Product: compiler-rt
           Version: 6.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: asan
          Assignee: unassignedbugs at nondot.org
          Reporter: adembo at gmail.com
                CC: llvm-bugs at lists.llvm.org

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
(http://krbdev.mit.edu/rt/Ticket/Display.html?id=7981). 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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190222/1a5f110e/attachment-0001.html>


More information about the llvm-bugs mailing list