2

Does editing a file and saving it permanently overwrite it? Is this a foolproof method of data destruction? I have a file that I need to fully erase, is this the way? I am running Linux and the file is on a hard drive.

Anders
  • 64,406
  • 24
  • 178
  • 215
bobiscool
  • 31
  • 1
  • 3
    Possible duplicate of [How can I reliably erase all information on a hard drive?](https://security.stackexchange.com/questions/5749/how-can-i-reliably-erase-all-information-on-a-hard-drive) – ximaera Jan 26 '18 at 07:20
  • Doesn't really seem like a duplicate, as the first part of the question is not answered by that. – forest Jan 26 '18 at 14:09

1 Answers1

3

This depends on the specific application. Some applications will only overwrite the individual block or blocks which you have edited. Others will, more often, create a new copy of the file under a new, temporary name, then rename it, deleting the old file. This is no more "secure" than simply deleting the file directly. You would have to have an application specifically designed to overwrite the entire file.

Neither of these techniques will overwrite the entire file. In order to do that, you will need to overwrite each block in-place. This can be done with specialized tools such as shred(1). Note that modern filesystems are complex, and there can still be remnants of data left over. For example, ext4 can keep small files that fit in a single inode in the inode itself. The inode is backed up in the journal, which is not overwritten when the inode is overwritten. Filesystems that support copy-on-write such as btrfs act like SSDs in that a single write to a given block will not necessarily overwrite the original sector on the drive where it is stored. The only real solution to eliminating sensitive information is to keep it encrypted and throw away the key before deletion.

Editing in-place

A file is composed of a large number of sectors, each of a size like 512 bytes. A sector often (but not always) maps to a filesystem block, with a sector being a physical unit of storage from the storage medium hardware, and a filesystem block being a single unit of storage as seen logically by the filesystem driver. A sector write is atomic (in theory), and editing a single byte requires writing to the entire sector it is in (although the disk uses read-modify-write to ensure that other data in the sector is not lost). Editing a file in place will only result in overwriting the sectors which contain the data being modified. Assuming you are using a filesystem that does not do copy-on-write (on Linux, pretty much everything but btrfs and ZFS), this will overwrite only the specific data being edited.

A C implementation which writes a string in-place at the 1234th byte:

void edit(void)
{
    int fd = open("file.txt", O_RDWR);
    pwrite(fd, "Hello, world!", 13, 1234);

    fsync(fd);
    close(fd);
}

Atomic editing

Often, applications will edit files by creating a new file with a temporary name and populating it with the modified contents of the old file. After it has been written (and optionally synced to disk), it is renamed to the original name, resulting in the old file being deleted, but still present on the disk. This is atomic, meaning that either the file is fully edited, or not edited at all. The intention is to ensure a crashed system which only has time to do a partial write will not corrupt the target file. Renaming is (or at least is supposed to be) an atomic operation. That is, it either fully succeeds, or fails, with no in-between.

A C implementation which copies the file and writes a string at the 1234th byte:

void edit(void)
{
    int src_fd = open("file.txt", O_RDONLY);
    int dst_fd = open("file.txt.tmp", O_CREAT|O_RDWR);

    sendfile(dst_fd, src_fd, NULL, -1);
    pwrite(dst_fd, "Hello, world!", 13, 1234);

    fsync(dst_fd);
    rename("file.txt.tmp", "file.txt");

    close(src_fd);
    close(dst_fd);
}

Overwriting in-place

To overwrite an entire file, you need to open the file (without truncating it), and write non-sensitive data to it. The amount of data written should be equal to the original file size, or else it will be unnecessarily appended to. Note that this only works assuming the filesystem does not have any tricks up its sleeve that result in there being data remnants lying around.

A C implementation which overwrites an entire file with random data:

void overwrite(void)
{
    struct stat sb;

    int src_fd = open("/dev/urandom", O_RDONLY);
    int dst_fd = open("file.txt", O_WRONLY);

    fstat(dst_fd, &sb);
    sendfile(dst_fd, src_fd, NULL, sb.st_size);
    fsync(dst_fd);

    close(src_fd);
    close(dst_fd);
}
forest
  • 64,616
  • 20
  • 206
  • 257
  • 1
    Not only does it depend on the application, it depends on the filesystem. A copy-on-write filesystem such as BTRFS or some of the flash-oriented filesystems don't overwrite in place even if the application tries to do so. – Mark Jan 26 '18 at 10:23
  • Indeed. I mentioned that in the second paragraph. The rest of the answer is about logical blocks only. – forest Jan 26 '18 at 14:08