There are three main types of storage drives. Hard disk drives, solid state drives, and solid state hybrid drives. Each of them behaves differently.
Hard Disk Drives
When you delete a file, you unlink it, effectively telling the filesystem that the sectors in which the file resides are no longer in use and are free to be overwritten. When this happens, the file is said to be present in unallocated space. Filling up an entire drive, in theory, will fill up every sector, including the ones which the unlinked file resided in, overwriting it. This is true for hard drives in most cases (rare exceptions include when a sector on a hard drive goes bad, and the hard drive is unable to write to it, causing the damaged data to be stuck in place). In general, you can assume that a single overwrite of any given sector is sufficient to destroy the underlying data. Random data is often said to be better than zeros. If you are on Linux, you should probably avoid using
/dev/urandom as it is very slow. A very fast and sufficiently random alternative to create a random file to fill up all your free space would be the following:
# key=$(head -c 16 /dev/urandom | base64)
# openssl aes-128-ctr -nosalt -k $key -in /dev/zero -out /fillfile
# rm /fillfile
It's important to do this as root because some filesystems, such as ext4, have a certain amount of the filesystem reserved for the root user only. On ext4, this is 5% of the entire drive space by default. This is designed to prevent a regular user from filling up the entire drive and preventing daemons running as root from writing their important log files to the disk. However it also interferes with filling up the entire disk, so you must create the random file using root.
You can test if your drive has any bad sectors with the
smartctl command. Install the
smartmontools package, and run the following:
# smartctl -A /dev/sda | grep Reallocated_Sector_Ct | grep -o '[0-9]*$'
This should output the number of bad sectors on your drive. The first command lists a bunch of data about drive errors, the second command singles out the error related to bad sectors, and the third command displays only the last number, which is the raw value of relocated (bad) sectors in the drive's lifetime. In most cases, this value will be 0. If the number is higher, some data may still be left over on your drive. In theory, this could contain sensitive information. Each sector's size is typically 512 bytes (or 4096 bytes on some modern drives). If the number is very large, then you've got other problems to worry about, because your drive is about to fail soon, and you should probably back it up and wipe it before it dies on you. Note that this issue applies to solid state drives as well.
Solid State Drives
SSDs are a bit different. They contain an extra area called overprovisioning space, which is not accessible by the operating system. Due to wear leveling, filling the entire drive may not actually delete all your previous data, and files in unallocated space may remain in the overprovisioning space. Each time you fully fill up an SSD, you have only a statistical chance of overwriting any given sector, and there's a small chance that the sector will not be overwritten, and will instead be part of the overprovisioning space. Now, you can issue the TRIM command to some SSDs, which tells the firmware to erase the contents of all unallocated space. However, you have to trust the firmware to do it properly, and many do not. Additionally, there is no research on whether or not TRIM destroys data in a way that ensures it cannot be recovered with specialized hardware, as far as I am aware, even if you could trust the firmware to erase cells promptly.
(Since I wrote this, there is evidence of data being recovered from erased flash memory, even after multiple writes.)
On Linux, you can mount your filesystem with the
discard option, or you can periodically run the command
fstrim / (with
/ replaced with the mountpoint of any SSD you want to TRIM). Using fstrim has less overhead. Doing this is good for performance, and also helps make sure that data which is deleted is harder to recover. If you use disk encryption, you may want to avoid using TRIM however, for reasons this article explains quite nicely.
Solid State Hybrid Drives
SSHDs are hard drives which contain a small (several GiB) built in solid state drive which they use for caching reads and writes in order to speed up the drive without being as expensive as a full solid state drive. I don't believe you can issue the TRIM command to these drives, or even control the solid state component of these drives at all. The behavior of these drives is entirely dependent on the firmware of the drives, and is entirely unpredictable. Such drives could easily send all consecutive writes to the hard drive platter and only send random writes to the solid state drive, causing a large file used to overwrite the drive to overwrite none of the solid state drive at all, leaving plenty of sensitive data there. I would not use these drives if you want to be able to overwrite files at a whim.
Instead, if you need to hybridize an HDD and SSD, you could buy a small caching SSD and a larger HDD, and combine them using software such as bcache, which is far more efficient than crappy SSHD firmware, but also easier to wipe data off of if you need to. To wipe data off of them, you can disconnect the caching drive, essentially turning the system back into a regular HDD, then securely erase everything from the SSD, fill the HDD with a large file, and reconnect the SSD and turn it back into caching drive.
In summary, it's not easy to securely overwrite data by filling your hard drive with a large file. There are so many caveats to be aware of. If there is any chance that sensitive files may ever touch your hard drive, you should use full disk encryption. That is the only way to ensure your data is secure.