Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am not talking about recovering deleted files, but overwritten files. Namely by the following methods:

# move
mv new_file old_file

# copy
cp new_file old_file

# edit
vi existing_file
> D
> i new_content
> :x

Is it possible to retrieve anything if any of the above three actions is performed assuming no special programs are installed on the linux machine?

share|improve this question
2  
You mean apart from your backups? –  jasonwryan Aug 9 at 2:03
    
@jasonwryan, yes, of course. –  Question Overflow Aug 9 at 2:03
2  
I just want to point out that your first example (mv) is akin to deleting old_file, not overwriting it, so methods (if any exist) for recovering deleted files, as opposed to overwritten files, would apply in that case. Your other two examples do indeed overwrite an existing old_file and existing_file, respectively. –  Celada Aug 9 at 4:40
    
All three examples you provided are implemented by deleting all the original file's data blocks and writing to newly-allocated blocks, and the procedure for recovering that data is the same as recovering a deleted file. An exception might be if the original files are exceedingly short (shorter than 60 bytes on ext4) where the latter two examples likely make the previous data unrecoverable. –  Mark Plotnick Aug 9 at 13:46
1  
@MarkPlotnick, according to Celada's comment, mv is different. –  Question Overflow Aug 10 at 3:33

2 Answers 2

up vote 2 down vote accepted

The answer is "Probably yes, but it depends on the filesystem type, and timing."

None of those three examples will overwrite the physical data blocks of old_file or existing_file, except by chance.

  • mv new_file old_file. This will unlink old_file. If there are additional hard links to old_file, the blocks will remain unchanged in those remaining links. Otherwise, the blocks will generally (it depends on the filesystem type) be placed on a free list. Then, if the mv requires copying (a opposed to just moving directory entries), new blocks will be allocated as mv writes.

    These newly-allocated blocks may or may not be the same ones that were just freed. On filesystems like UFS, blocks are allocated, if possible, from the same cylinder group as the directory the file was created in. So there's a chance that unlinking a file from a directory and creating a file in that same directory will re-use (and overwrite) some of the same blocks that were just freed. This is why the standard advice to people who accidentally remove a file is to not write any new data to files in their directory tree (and preferably not to the entire filesystem) until someone can attempt file recovery.

  • cp new_file old_file will do the following (you can use strace to see the system calls):

    open("old_file", O_WRONLY|O_TRUNC) = 4

    The O_TRUNC flag will cause all the data blocks to be freed, just like mv did above. And as above, they will generally be added to a free list, and may or may not get reused by the subsequent writes done by the cp command.

  • vi existing_file. If vi is actually vim, the :x command does the following:

    unlink("existing_file~") = -1 ENOENT (No such file or directory)
    rename("existing_file", "existing_file~") = 0
    open("existing_file", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 3

    So it doesn't even remove the old data; the data is preserved in a backup file.

    On FreeBSD, vi does open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664), which will have the same semantics as cp, above.


You can recover some or all of the data without special programs; all you need is grep and dd, and access to the raw device.

grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file

dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)

You'd also want to read some blocks before and after that block. On UFS, file blocks are usually 8KB and are usually allocated fairly contiguously, a single file's blocks being interleaved alternately with 8KB blocks from other files or free space. The tail of a file on UFS is up to 7 1KB fragments, which may or may not be contiguous.

Of course, on file systems that compress or encrypt data, recovery might not be this straightforward.


There are actually very few utilities in Unix that will overwrite an existing file's data blocks. One that comes to mind is dd conv=notrunc. Another is shred.

share|improve this answer
    
Thank you for explaining the inner mechanics of the three different operations. This is really useful! –  Question Overflow Aug 16 at 2:04
    
btrfs is pretty resilient to deleted files. It tends to use blocks in a round-robin fashion, so if you have enough space on the device the file will not be overwritten for a long time. See here –  pqnet Aug 17 at 18:09

I'm going to say no (with a giant asterisk).

Think about how data is laid on a disk. You have blocks which contain data and point to the next block (if there is one).

When you overwrite data you are changing the block contents (and if you are extending the file all the ending marker). So nothing should be able to be recovered (see below).

If you shorten the file, then you are loosing the old blocks and they will soon be recycled. If you're a programmer, think of a linked list where you "lose" half of your list without doing a free/delete. That data is still there, but good luck finding it.

Something that might be interesting to think about is fragmentation.

Fragmentation occurs when you have "holes" of non-contiguous data on your disk.This can be caused by modifying files such that you extend or shorten them and they no longer fit in their original spot on the disk.

In the event of having a file grow past its original size (it needs to move at this point), depending on your filesystem you may copy the entire file to a new location where the old data would still be there (but marked as free) or you just change the old ending pointer and have it point to a new location (this will lead to thrashing).

The long story short, your data is probably lost (without going through an extreme forensic process where you look at it under a microscope); however, there is a chance that it is still there.

share|improve this answer
1  
Your answer makes the assumption that a block-based non-copy-on-write filesystem such as ext4 or xfs is in use. With copy on write filesystems such as zfs and btrfs you are in fact never "changing the block contents"; those filesystems always use brand new blocks to contain new data. Also, log-based filesystems like jffs2 also always write new data to new locations (not "blocks", those filesystems are not block-based). That being said, this doesn't mean it's easy to find where the old data live and to do it before the space is recycled. So your answer, which is no, is still correct –  Celada Aug 9 at 4:51
    
@Celada Thanks! I found that very informative. I haven't had the time to look at how btrfs or zfs works, but I knew they exist. –  SailorCire Aug 9 at 15:18
1  
Thank you for providing some useful insights. –  Question Overflow Aug 10 at 3:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.