19:28
11
A: Can a storage device completely erase itself while performing the erase?

davidgoYes, of course it can. Programs load into memory - so once they are in memory the disk they are in can be wiped and the program can continue to run. You just need to ensure the program is small enough to be fully loaded in memory. This is not a hard task if you keep the program small. Even if i...

I just tried a trivial test by copying the Linux "shred" command and trying to run it to shred itself. It did not work, giving me the error "failed to open for writing: Text file busy" - and Googling that it appears there are some glibc level protections preventing a file from being deleted while it is running - so it looks like you would need to write the program to delete itself in such a way as to not trigger this function. stackoverflow.com/questions/16764946/… talks about this, and you may be able to do so by calling unlink.
Not exactly what you asked closely related - copying the "rm" binary to /tmp and running /tmp/rm /tmp/rm worked perfectly.
The difference is that shred tries to overwrite the contents of the file, which older Linux kernels would disallow, in newer kernels it's allowed (but can cause the program to crash), while rm just unlinks it without changing its contents. The issue is that programs don't necessarily load into memory in full; the executable and library files are paged-in as needed, and if the file is overwritten that'll also overwrite code in the page cache. (or e.g. if the physical storage disappears, the program will run from page cache but will crash if it needs to load the remaining code.)
the temporary ext4 might work but seems overkill; it'll be easier to use an in-memory filesystem, such as tmpfs (most Linux systems already have a tmpfs at /run these days, and often but not always at /tmp, and you can copy e.g. Busybox to it).
superuser.com/a/1282493/10165 this answer goes in depth into a process of doing it. I don't want to copy a complete answer, and it covers some of the same approaches you do with one critical minor difference
"depending on the OS" - since the question doesn't say you have to be using any particular OS, presumably you're allowed to equip the disk with some kind of bootloader that loads the entire OS into RAM, same as you're saying to load the program into RAM. The key is that you need to make sure the OS doesn't crash until after the last byte of storage is clean :-) Without endorsing particular software, this is sometimes known as a "boot and nuke".
... you would need to use hardware that's willing to boot from the storage device in question: or equivalently you have to deal with any requirement for signed bootloaders and whatnot.
@stevejessop As my answer demonstrated you don't need to boot the OS into a ramdisk.
19:28
@davidgo: no, agreed you don't need to. Running the OS from elsewhere is a sufficient condition but not a necessary one. If the questioner tries your technique, and the OS does crash because (for example) it tries to swap from disk space that has already been overwritten, then they won't be able to reproduce your results, but there are bigger hammers they can try. Although they've already ruined their OS, so they can't just go again with the same storage device...
It may be that we're solving different problems, though. I took it that the questioner wants to erase the whole storage device, whereas you are demonstrating erasing 100k of the storage device including the bit that stores the program doing the erasing. It's not demonstrated whether your technique would work if instead of just erasing dd you were erasing the storage's block device mount point.
@SteveJessop agreed we were answering slightly different questions, however the answer is the same - Indeed in the second example I did erase the storage block device mount point. This leaves open the very small question of "can this be done on the root device", and the answer, from unfortunate experience is yes - it is all to common for people to specify the wrong device when using dd and land up with a bricked system. askubuntu.com/questions/794213/… answers this question exactly.
@davidgo: my concern is not whether it can work, but how sure it is to work. It's pretty well guaranteed to brick your system, I'm just not convinced that it's guaranteed to successfully wipe the whole disk before it crashes (and as someone points out in one of those answers, even if it is wiped, swapped pages could "un-wipe" data by writing RAM back to disk after that bit of disk was wiped). The whole question's arguably moot, though, since a power failure or something could stop it working anyway, past the point the system is bricked. Buy another storage device :-)
/tmp/dd if=/dev/null bs=102400 > /tmp/dd gets the shell to open("/tmp/dd", O_TRUNC|...) for the redirect after fork but before execve of /tmp/dd. When I try the same thing with strace /tmp/dd ... > /tmp/dd, I get -1 ENOEXEC (Exec format error). But bash reports no error because it treats an empty file is a valid shell script. strace bash -c /tmp/dd reports the same failure of execve, but then Bash makes open and read system calls.
Anyway, > /tmp/dd is obviously fatally flawed. of=/tmp/dd is much more interesting. Also, maybe you meant to read from /dev/zero (infinite stream of 0 bytes) rather than /dev/null (empty file). With strace /tmp/dd if=/dev/zero bs=102400B of=/tmp/dd, I get a successful openat(AT_FDCWD, "/tmp/dd", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3, but then the next thing is a SIGBUS when the executable tries to demand-page more of itself, but the file backing the mappings for .text/.rodata and .data has now been truncated. It's the same as mmap and truncating the underlying file.
Of course none of this would apply if writing to the block-device holding the filesystem. Then, as long as the executable and libraries are hot in disk cache, the kernel won't notice anything because raw disk writes aren't coherent with what the filesystem driver is doing; it assumes nobody else will be messing with a filesystem while it's mounted.
I know that this all is true because Linux/Unix holds a handle to an opened file, where the actual file can be unlinked in the meanwhile. But is this also true for Windows? AFAIK, Windows refuses to delete an opened file. Is a program file also prevented from being deleted as long as there is a process of this program file?
On Unix-based systems, it is common for a new process not be loaded at once, but pages to be loaded (or re-loaded, if there were previously swapped out) on demand. That's why the executable is busy. Also, it would be a good idea to unmount the filesystem(s) sitting on that device before erasing it. It all points to making of the utility on a RAM disk first.
19:28
@rexkogitans: note that truncating a running executable does cause a problem; see my previous comment re: SIGBUS on /tmp/dd if=/dev/zero of=/tmp/dd count=102400B doing open(O_TRUNC). If you unlinked a file and created a new one, you'd be fine, but that couldn't "shred" the blocks that were holding the old file.
@PeterCordes Well, but that does not answer the question contained in my comment. My comment was about improving the answer by mentioning how Windows behaves (sorry, after > 20 years of Linux I am a complete Windows-Noob).
@rexkogitans: Yeah, I know it doesn't. I think Windows has multiple APIs for file access, and backup programs can at least open and read files that are already open and running. I seem to recall that system-update programs have to queue replacement of running executables to be done by the OS during reboot. Because yeah, you can't unlink or even rename a running executable on Windows, AFAIK.