Re: More info on dd?

From: Valdis.Kletnieksat_private
Date: Fri Oct 18 2002 - 07:09:12 PDT

  • Next message: Gary L. Palmer: "Re: Future trends in computer forensics"

    On Tue, 15 Oct 2002 20:05:23 CDT, Ed Carp said:
    
    > Hmmm, don't know why - it's not that tough to do:
    
    Actually, it *is*.  It's actually *VERY* hard to get right, as the attached
    code shows...
    
    >     fn[strlen (fn) - 1] = NULL;
    
    Hmm.. so if filename is "foo", then strlen(fn) will be 3, and you just
    truncated it to "fo".  Is that what you wanted?
    
    >     chmod (fn, 0622);
    
    Bad Juju here - either you're wiping a /dev/hd type entry, in which case
    you should NOT make it 0622 (because then anybody can bypass permissions
    on the file system you later make on here), or you're wiping a single file
    (in which case it's Even Worse).  In any case, the chmod() is totally useless,
    and I don't understand why you're bothering.  If you insist on doing it,
    you should check the return codes...
    
    >     n = open (fn, O_RDWR);
    
    If you're intending to wipe *disks*, you might want to stat() it and check
    the st_dev, st_ino, st_mode, and st_rdev fields to make sure it's a disk rather
    than a regular file.  As coded, this will in addition chase symlinks too..
    
    Whoops. ;)
    
    >     for (i = 0; i < 4; i++)
    >     {
    >       printf ("\rSecure wipe '%s', pass %d", fn, i + 1);
    >       fflush (stdout);
    >       for (j = 0; j < 65535; j++)
    >         lbuf2[j] = a[i];
    
    Well-meaning, but the use of all-nulls (\0) as the first pattern may be
    very self-defeating (see below)...
    
    >       while (1)
    >       {
    >         if ((p = read (n, lbuf, 65530)) < 1)
    >           break;
    >         lseek (n, -1 * p, SEEK_CUR);
    >         if (EOF == write (n, lbuf2, p))
    
    This goes into the buffer cache...
    
    And if you're erasing a *file*, you have the added fun that you are *NOT*
    guaranteed that the blocks the write() call gets allocated are the blocks
    that the read() read from.  Several cases:
    
    1) If it's a "sparse" file with holes in it, there may not have been blocks
    allocated to start with for all-zeros blocks.
    
    2) There's nothing prohibiting a file system from freeing blocks that have
    become all zeros (and given the initialization of lbuf2, and the file system
    block size, it *could* result in 512 bytes written for the first block, and
    the kernel simply deallocating the all-zeros blocks for the *OTHER* 65020
    bytes. Particularly nasty if you use zeros as the first pass - the kernel
    may simply free all the blocks of a file, and then the next pass you get
    entirely new blocks...
    
    3) File systems that support compression (such as AIX's "jfs") will quite
    likely allocate DIFFERENT blocks than before, if the new data compresses into
    different number of blocks than the old data.  See (2) above as a special
    case...
    
    4) 'man fsync()'.  Understand *why* I say that.  If you don't, you'll never
    understand the issues involved here.. ;)
    
    >     close (n);
    >     unlink (fn);
    
    And the data in the file cache may never actually go to disk if the unlink hits
    before the disk blocks are pushed to disk.  In fact, on most systems, you are
    almost *guaranteed* that up to <whatever your bufcache size is> will *NOT* be
    written to disk.
    
    The use of '65530' rather than 2**16 may cause interesting effects performance
    wise....
    
    It's also recommended that you go and read Peter Gutmann's writings on this
    subject, starting with:
    
    http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
    
    It turns out that even if you *DO* manage to actually write to the correct blocks
    on the disk, that the data may not be as gone as you think....
    
    -- 
    				Valdis Kletnieks
    				Computer Systems Senior Engineer
    				Virginia Tech
    
    
    
    



    This archive was generated by hypermail 2b30 : Fri Oct 18 2002 - 08:32:14 PDT