Uploaded image for project: 'Lustre'
  1. Lustre
  2. LU-20971

lfs find: buffer overflow in parallel find on deep directory trees

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Medium Medium
    • None
    • Lustre 2.18.0
    • 3
    • 9223372036854775807

      With parallel find, a deep directory tree makes the worker threads write past the end of a heap buffer. As soon as a directory path is longer than about PATH_MAX - NAME_MAX, the names of its entries are appended past the end of a PATH_MAX + 1 allocation. Note the serial traversal does not have the problem.
      Also, a directory path longer than PATH_MAX is silently truncated by the snprintf() in work_unit_create(), while the serial traversal handles such paths (up to 2 * PATH_MAX).

      Reproducer, on a client with /mnt/lustre mounted (16 nested directories with 250-character names give a 4035-character directory path, plus a file with a 200-character name inside the deepest one):

      B=/mnt/lustre/deep; mkdir -p $B; cd $B
      c=$(printf "c%.0s" $(seq 1 250))
      for i in $(seq 1 16); do mkdir $c && cd $c; done
      touch $(printf "f%.0s" $(seq 1 200))
      cd /
      lfs find $B > /dev/null
      valgrind -q lfs find --threads 4 $B > /dev/null
      

      "lfs find $B" is aborted by glibc:

      double free or corruption (!prev)
      

      and valgrind reports the overflow:

      Invalid write of size 1
         at 0x4871880: strcpy (vg_replace_strmem.c:565)
         by 0x48BD4E3: llapi_semantic_traverse (liblustreapi_pfind.c:3303)
         by 0x48BD9F3: find_worker (liblustreapi_pfind.c:3442)
         by 0x4B81E97: start_thread (in /usr/lib64/libc.so.6)
         by 0x4BEC61B: thread_start (in /usr/lib64/libc.so.6)
       Address 0x50df3a1 is 0 bytes after a block of size 4,097 alloc'd
         at 0x48684C8: malloc (vg_replace_malloc.c:447)
         by 0x48BD283: work_unit_create (liblustreapi_pfind.c:3785)
         by 0x48BD283: work_unit_create_and_add (liblustreapi_pfind.c:3817)
         by 0x48BD65B: llapi_semantic_traverse (liblustreapi_pfind.c:3328)
         by 0x48BD9F3: find_worker (liblustreapi_pfind.c:3442)
      

            sebastien Sebastien Buisson
            sebastien Sebastien Buisson
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: