sys/vfs/hammer: Fix bug on erasing volume header
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Sun, 20 Mar 2016 09:09:28 +0000 (18:09 +0900)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Sun, 20 Mar 2016 10:23:11 +0000 (19:23 +0900)
commitbcc535d1f1de62c4c603593151aba54361a6a77c
tree76e97f06a7b6b656edd1ecefaaa739a13193260f
parent0b7c8f4cef679a6118c7d05631c644b3206d41d3
sys/vfs/hammer: Fix bug on erasing volume header

deabdbfb in 2015 had a bug in hammer volume-del ioctl which didn't
completely erase the volume header. hammer_ioc_volume_del() needed
to declare an ondisk volume variable instead of a pointer.

Having a pointer here caused bzero against the pointer itself
(within kernel stack of hammer volume-del), and then clear ondisk
volume header using kernel stack image.

The following [A] shows the volume deleted by hammer volume-del
has kernel stack itself for sizeof(struct hammer_volume_ondisk) bytes
which is 1928 bytes. It should be like [B] where 0-1928 bytes are
zero filled. [A] actually happens to erase the filesystem signature
(HAMMER_FSBUF_VOLUME) located at the first 8 bytes of the header
since it equals pointer size in x86_64, but it needs to properly
zero clear the whole header (1928 bytes) for security reason.

  [A] Before this commit
  # newfs_hammer -L TEST /dev/da2 > /dev/null
  # mount_hammer /dev/da2 /HAMMER
  # hammer volume-add /dev/da3 /HAMMER
  # hammer volume-del /dev/da3 /HAMMER
  # od -tx1 -N 1928 /dev/da3
  0000000    00  00  00  00  00  00  00  00  40  4d  31  23  e1  ff  ff  ff
  0000020    00  00  00  00  00  00  00  00  00  44  2a  52  e0  ff  ff  ff
  0000040    40  4d  31  23  e1  ff  ff  ff  18  68  30  c4  00  00  00  00
  0000060    30  66  29  1a  e1  ff  ff  ff  18  b6  5b  22  e1  ff  ff  ff
  ...

  [B] This commit
  # newfs_hammer -L TEST /dev/da2 > /dev/null
  # mount_hammer /dev/da2 /HAMMER
  # hammer volume-add /dev/da3 /HAMMER
  # hammer volume-del /dev/da3 /HAMMER
  # od -tx1 -N 1928 /dev/da3
  0000000    00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  *
  0003600

  [C] sizeof ondisk volume header
  # cat ./sizeof.c
  #include <stdio.h>
  #include <vfs/hammer/hammer_disk.h>
  int main(void) {
          printf("%d\n", (int)sizeof(struct hammer_volume_ondisk));
          return 0;
  }
  # gcc -Wall -g ./sizeof.c
  # ./a.out
  1928
sys/vfs/hammer/hammer_volume.c