Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Jun 1999 15:36:58 -0600
From:      Wes Peters <wes@softweyr.com>
To:        cjclark@home.com, FreeBSD Security <freebsd-security@FreeBSD.ORG>
Subject:   Re: Secure Deletion
Message-ID:  <3773F67A.CC9B6215@softweyr.com>
References:  <199906250212.WAA07810@cc942873-a.ewndsr1.nj.home.com>

next in thread | previous in thread | raw e-mail | index | archive | help
"Crist J. Clark" wrote:
> 
> I looked through a long thread from last month on this topic, but was
> unable to get an operable answer to my problem.
> 
> Problem: A file came onto a FreeBSD system. All traces of this file
> will (probably) need to be destroyed. The error was on someone else's
> part, so we did not find out until this file had
> propagated. There is presently an existing file that needs to be
> destroyed. In addition, there are existing files that had this
> information in them, but have since had the 'offending' part
> removed...
> 
> OK, OK, if you have not guessed, it was some email. One person got it,
> forwarded it, and someone else stored it in an IMAP mailfile. The
> offending stuff is 'gone' from the existing mailspools, but the IMAP
> file exists. So, the question is...
> 
> 1) Is there a way for me to securely destroy the file that still
>    exists? For example, if I were to do something like (this is just
>    an example),
> 
>    # BADLEN=`ls -l <bad_file> | awk '{ print $5 }'`
>    # dd if=/dev/zero    of=<bad_file> bs=1 count=$BADLEN
>    # dd if=/dev/urandom of=<bad_file> bs=1 count=$BADLEN
>    # dd if=/dev/zero    of=<bad_file> bs=1 count=$BADLEN


This won't do it, if you're really interested in obliterating the file 
contents.  What you want to do is overwrite the file blocks with 
alternating patterns of 10101010 then 01010101 at least 100 times.  
Due to the way modern recording formats work, and the memory of the 
cells that actually store the bits on the disk, anything less won't 
really erase the disk.

Fortunately, this isn't all that tough to do.  Here's a little program 
I just hacked together to do this.  It's not designed to be efficient, 
it just overwrites the data and syncs the file on every pass, but it 
should do a pretty good job of clobbering the bits on the disk.

If there is any interest, I'll write a man page for this and commit
it as well, or work it into 'rm -P' in some way.


/*
 * Obliterate - a simple program to obliterate file contents.
 *
 * Copyright (c) 1999 Softweyr LLC, South Jordan, Utah USA.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY Softweyr LLC ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL Softweyr LLC OR ANY CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Author: Wes Peters
 * Date: Fri Jun 25 14:22:33 MDT 1999
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include <stdio.h>
#include <fcntl.h>

void
obliterate(char *fname)
{
    struct stat S;
    int fd;
    void *data;
    int iteration;

    if (stat(fname, &S) == -1)
    {
	perror(fname);
	return;
    }

    if (!S_ISREG(S.st_mode))
    {
	fprintf(stderr, "%s: not a regular file\n", fname);
	return;
    }

    fd = open(fname, O_RDWR);
    if (fd == -1)
    {
	perror(fname);
	return;
    }
    
    data = mmap(NULL, S.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    if (data == MAP_FAILED)
    {
	perror(fname);
	close(fd);
	return;
    }

    /*
     * Overwrite the file 100 times with successive iterations of 0101 then
     * 1010 patterns.
     */
    for (iteration = 0; iteration < 100; iteration++)
    {
	(void) memset(data, 0xa, S.st_size);
	if (fsync(fd) == -1)
	{
	    perror(fname);
	    close(fd);
	    return;
	}

	(void) memset(data, 0x5, S.st_size);
	if (fsync(fd) == -1)
	{
	    perror(fname);
	    close(fd);
	    return;
	}
    }

    /*
     * Zero the file blocks against casual perusal, then unlink the file.
     */
    memset(data, 0, S.st_size);
    if (fsync(fd) == -1)
    {
	perror(fname);
	close(fd);
	return;
    }

    close(fd);
    if (unlink(fname) == -1)
    {
	perror(fname);
    }

    return;
}


/*
 * Obliterate each file named on the command line.
 */

int
main(int argc, char *argv[])
{
    while (--argc)
    {
	obliterate(argv[argc]);
    }

    return 0;
}




-- 
       "Where am I, and what am I doing in this handbasket?"

Wes Peters                                                 Softweyr LLC
http://www.softweyr.com/~softweyr                      wes@softweyr.com


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3773F67A.CC9B6215>