SeedSigner / seedsigner-os

SeedSigner OS | Minimal Raspberry Pi image made for SeedSigner
MIT License
97 stars 25 forks source link

Why is there a "write" to microsd on the very first boot? #37

Closed jdlcdl closed 1 year ago

jdlcdl commented 1 year ago

Inspired by questions and a convo w/ "Robert Brian" this mornign in the seedsigner telegram group.

I've found that SeedSignerOS appears to write to the microsd during the very first boot after writing the microsd.

tl;dr: I'm trying to use dd to get a checksum of a microsd as a baseline, and then be able to verify it has not changed in the future, after much activity, by comparing my baseline checksum.

My write-up, intended for Mr. Brian...

I'd mentioned that I suspect we can verify that our microsd has not been touched, so here is my hypothesis for how we might do so:

1) start by zeroing the microsd... this way we can compare it to what other users might see. Better than this would be to /dev/random our microsd. I'll call my microsd /dev/microsd even though it's really /dev/sdf for me. dd if=/dev/zero bs=8M of=/dev/microsd status=progress this took the better part of an hour for my 32GB microsd, I killed it with sudo pkill dd after it ran out of space and wouldn't exit on its own.

To make sure I've got all zeros, I compared the first 64M of my microsd to 64M of /dev/zero. dd if=/dev/zero bs=64M count=1| sha256sum and dd if=/dev/microsd bs=64M count=1 | sha256sum both gave me the same output

1+0 records in
1+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 0.328032 s, 205 MB/s
3b6a07d0d404fab4e23b6d34bc6696a6a312dd92821332385e5af7c01c421351  -

This is enough because: 1) I know that SeedSignerOS is going to be written on the first 36M of my microsd, and 2) we sort of have to cut this corner if we expect to be comparing against others with different microsd sizes.

Write SeedSigner OS onto the microsd sudo dd if=~/Downloads/SeedSignerOS_0_5_1_EXP.img of=/dev/microsd status=progress gives me output like:

28439040 bytes (28 MB, 27 MiB) copied, 3 s, 9.5 MB/s 
69633+0 records in
69633+0 records out
35652096 bytes (36 MB, 34 MiB) copied, 5.93515 s, 6.0 MB/s

OK, Let's see what that checksum looks like, being careful to only look at the blocks written to our microsd. sudo dd if=/dev/microsd count=69633 | sha256sum gives me output like:

69633+0 records in
69633+0 records out
35652096 bytes (36 MB, 34 MiB) copied, 1.80364 s, 19.8 MB/s
ac74b29ca9194c0a1e0eef8427b166336d1d1d3ba451753940a843a4aaa69193  -

Cool, that happens to be the same hash that our repo says we should have downloaded when installing the 0.5.1 SeedSigner OS image.

Now let's see what the checksum is for the first 64M, assuming that we'll catch any future writes as long as they change existing bits or extend that filesystem. sudo dd if=/dev/microsd bs=64M count=1| sha256sum

1+0 records in
1+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 3.68302 s, 18.2 MB/s
5431895fe9640a490bf26d9880ed4fd13b7048939c71b4e86911d595783603df  -

This is close, but it is not yet our baseline. 1) It is my experience that the microsd will get written the very first time we boot. I don't know why but I'm going to ask @DesobedienteTecnologico about it.
2) We want to setup our persistent settings to our liking, so that will write to the microsd as well.

So, remove the microsd from the computer, insert it into seedsigner, and let seedsigner boot fully, then setup your persistent settings however you like. DO NOT LOAD ANY SEEDS. Just pull power, and remove your microsd card so that we can get a final baseline hash using the steps above.

With the microsd back in your computer, get your new baseline. sudo dd if=/dev/microsd bs=64M count=1| sha256sum

If what I'm suggesting is sound, it should not change in the future unless we change our persistent settings with the microsd inserted.

Unfortunately, I'm using an old pi2 and a self-built SeedSigner OS w/ version 0.5.2, so my baseline is going to look different than yours (maybe yours will look different than everyone else's because of that un-explained write that happens on the very first boot.). My microsd card is returning the same hash as my baseline after a few reboots, after a few loads of different seeds, and after 1 signed transaction on testnet. I'll reference this message in the future if I notice that my microsd changes after repeated activity.

(for my own future reference), with a self-built seedsigner_0.5.2 for pi2 having hash 8eef773e71751fbba30ccc292d4bde2ca9e8076ed65f3404dddb9013b0e510f8, my baseline after first boot (and much activity aftewards, never saving persistent settings) looks like:

sudo dd if=/dev/sdf bs=64M count=1| sha256sum
1+0 records in
1+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 3.5751 s, 18.8 MB/s
9b1e01f5f3e0220959d4eb3639e23518b2e88edb5342bf7f52d9adf4ea226599  -
jdlcdl commented 1 year ago

Btw: this is repeatable.

I can zero my microsd card, then write my custom version of seedsigner onto and even extract the exact hash that matches that file.

If I boot once, fully, and do nothing, then yank it... I get a different hash when I check my microsd.

I can do this again and again, I always end up with a changed hash that matches the last time I tried this.

It is not at all worrisome to me, because after that first boot, it stops changing. I'm just hoping to be able to explain it.

jdlcdl commented 1 year ago

If it is at all helpful,

sudo dd if=/dev/sdf bs=35652096 count=1 | cmp -l - ~/Downloads/seedsigner_0_5_2.img gives me:

     550   1   0
1+0 records in
1+0 records out
35652096 bytes (36 MB, 34 MiB) copied, 1.75199 s, 20.3 MB/s

I read that as the only write that is occurring on first boot is that byte 550 (knowing cmp starts at index 1) is being changed from 0x00 to 0x01

I can confirm that if I change that byte from 0x00 to 0x01 in the original custom 0_5_2 for pi2 image, I am getting the same hash that I pull off my microsd card after the first boot. This is what it looks like in hexedit (we're looking at byte 0x225 here because hexedit starts at 0). hexedit_byte_550

jdlcdl commented 1 year ago

https://forum.cgsecurity.org/phpBB3/viewtopic.php?t=1791

No idea if this is related, but in this thread, someone is talking about 0x41 not being the same, and that's the same byte before the 0x29 that I'm seeing. Some talk of a "dirty bit" in boot sector to signify that something was not written correctly in the past?

DesobedienteTecnologico commented 1 year ago

@jdlcdl Thanks for your research on this.

That is probably because of "Dirty bit". We actually remove the MicroSD without umounting it from system... Long time ago, we were talking about to remove MicroSD manually or not. And we end up to do it without umounting it, to be easier for all users. "Just power ON and release MicroSD".


True it adds a single bit, which changes the hash of all MicroSD: image

inode.c

But the good news are that the files integrity still in ALL files. They still have the same hash even having the "Dirty bit".

This can be probably solved umouting manually, but all users will need to umount it manually and probably isn't that handy for user experience.


The best approach I could do, is to verify the files hashes with something like:

sha256sum * 

Here goes mine from https://github.com/SeedSigner/seedsigner/releases/download/0.5.1_EXP/SeedSignerOS_0_5_1_EXP.img:

f4c9a9f6556ea3d24ffb216bb7f9c512035fae15a4c9c89c42b53a4f86f55017  bcm2708-rpi-b.dtb
3cc3738d3470e0d193222268628e65e015792c6c2ae061571eed84b4b1d5b11a  bcm2708-rpi-b-plus.dtb
29e5cf16a2ccd6f78cce9639c936405583f82fafb16a8afb34bc0fcf5c774382  bcm2708-rpi-zero.dtb
bb9cda6053e34057bd8e61e2431c41c4aef41f1b31fd9606a6e4e496b7617ae2  bcm2708-rpi-zero-w.dtb
4c0b766693d7e7e90e5b89c1edbfaee8fa957973ab1169940bbe79aedd2b43ba  bcm2709-rpi-2-b.dtb
b008b8809587cccc5d949baa17dfd769e4ae23b45c15317de64423e4942f0c44  bcm2710-rpi-3-b.dtb
e9edb014025f05c5fa746a6e8a925f4ea3695d631dda0bfb9bd502aa76f20b7c  bcm2710-rpi-3-b-plus.dtb
2f094dba5607251c0e73cf01c865deba6bd199a4fdd45acf6b942952df3d33db  bcm2710-rpi-zero-2-w.dtb
b5072dbcaa1d2d92d9e4ac382fe030ad7c3bde203f1f12e75aa3c80f80ef963c  bcm2711-rpi-4-b.dtb
7d2c9ba22bddb57d24d56bbf6b0a073eb389d5dd6e58b45379fae2a67ce6c241  bcm2837-rpi-3-b.dtb
69309823da13dc96b89e3d82b44f820e4f84efa79d207adad2c8784559794f03  bootcode.bin
f717f8ddd291ec4a6cf6d0808c61cf65ef9453ed68deddfbf78fd37036c701f4  cmdline.txt
95a6bdc89000d71bdd57143e402fae84818ff404349c318b71418e99ef36f446  config.txt
5837c8f36125e593006d7ee2bbded46a596ac5641bcfc4b2951b934522bd52cf  fixup_x.dat
f9773f18f318e6e1254d5ba9b41753fdd944dab6076219526d3879cfc2f749df  start_x.elf
83ee666b2fd309abb9ab061cd145707731a8a3874648b2ca8972cf0b2259cc9b  zImage

Ping @newtonick @SeedSigner in case they want to add someting about this.

jdlcdl commented 1 year ago

This explanation is perfectly reasonable! Thank you!

DesobedienteTecnologico commented 1 year ago

This explanation is perfectly reasonable! Thank you!

Thanks for your time and the enthusiasm with this! :)

Please feel free to Close the Issue if you think that it get solved to you.