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