btrfs-progs: use ftw() unstead of system("du")
authorZach Brown <zab@redhat.com>
Thu, 17 Jan 2013 23:23:10 +0000 (15:23 -0800)
committerZach Brown <zab@redhat.com>
Wed, 6 Feb 2013 00:09:38 +0000 (16:09 -0800)
commit9e4ad990992ebb588c599832d8d7dc0fe2a37475
treedc0e0f8b355c09da5ff2a171089f70391a7e8da0
parent968efc6f988623aff2b4c21af8317ec80836a4b9
btrfs-progs: use ftw() unstead of system("du")

size_sourcedir() uses shockingly bad code to try and estimate the size
of the files and directories in a subtree.

- Its use of snprintf(), strcat(), and sscanf() with arbitrarily small
  on-stack buffers manages to overflow the stack a few times when given
  long file names.

  $ BIG=$(perl -e 'print "a" x 200')
  $ mkdir -p /tmp/$BIG/$BIG/$BIG/$BIG/$BIG
  $ mkfs.btrfs /tmp/img -r /tmp/$BIG/$BIG/$BIG/$BIG/$BIG
  *** stack smashing detected ***: mkfs.btrfs terminated

- It passes raw paths to system() allowing interpreting file names as
  shell control characters.

  $ mkfs.btrfs /tmp/img -r /tmp/spacey\ dir/
  du: cannot access `/tmp/spacey': No such file or directory
  du: cannot access `dir/': No such file or directory

- It redirects du output to "temp_file" in the current directory,
  allowing overwriting of files through symlinks.

  $ echo hi > target
  $ ln -s target temp_file
  $ mkfs.btrfs /tmp/img -r /tmp/somedir/
  $ cat target
  3 /tmp/somedir/

This fixes the worst problems while maintaining -r functionality by
tearing out the system() code and using ftw() to walk the source tree
and sum up st.st_size.

Signed-off-by: Zach Brown <zab@redhat.com>
kerncompat.h
mkfs.c