-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
eboot: .RODATA, upstream uzlib, move CRC, save 112 bytes (#7844)
RODATA can be copied automatically by the bootrom, so no reason not to allow its use for strings and constants in eboot.c Revert to pfalcon's original uzlib since the single patch to remove RODATA is not required. Rationalize eboot.ld linker script, clean up BSS and init it in code. Saves 112 bytes of space in the bootloader sector by removing the extra code associated with literal loads. * Move CRC out of bootload sector We added protection to only erase the bootload sector when flashing an image when the new sector != the old sector. This was intended to minimize the chance of bricking (i.e. if there was a powerfail during flashing of the boot sector the chip would be dead). Unfortunately, by placing the CRC inside the eboot sector *every* application will have a unique eboot sector (due to the crc/len), so this protection doesn't work. Move the CRC into the first 8 bytes of IROM itself. This frees up extra space in the boot sector and ensures that eboot won't be reflashed unless there really is an eboot change.
- Loading branch information
1 parent
6c564c2
commit 07b4c09
Showing
9 changed files
with
67 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty certain that the change to the CRC placement in elf2bin.py has broken the segment checksum. I'll investigate a little more and hopefully propose a patch.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@einglis Are you trying to fix a problem you're seeing somewhere? Can you explain why you need to fix it?
I believe you are technically correct with your observation, however the 1-byte checksum is ignored by eboot.c (the only thing to use the 2nd array with the invalid .text c'sum). Actually, since it's .text and already in ROM at the right address, eboot doesn't do anything at all with this section other than skip it.
The ROM only ever looks at the 1st structure (which contains eboot's sections), and that does have a proper c'sum. You can verify this by running
esptool image_info
.You're free to propose a fix to elf2bin, but it's not going to actually change anything that I can see (since, again, the c'sum byte is completely ignored in the 2nd stage bootloader).
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the response, @earlephilhower. My application accepts uploaded binaries for upgrades (nothing magic there), but I wanted to avoid bricking devices by being a little more careful with their validation. I thought the segment checksums would be a quick-win here.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the c'sum is used on boot not update/reflashing. The eboot copy command (for upgrade) just...copies, nothing more. It'll copy garbage if you ask it to.
You can always use signing to crypto-ensure updates are valid as received, but unless you expect the TCP stream (which is CRC protected with retry on mismatch) itself to corrupt data it feels like overkill.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using the Update library, and while it does superficial checking of the supplied data (it checks the start byte, but I don't recall whether it checks the checkum), it only considers the boot image, not the main image that follows.
Hence - just like you describe for the boot process - it will accept pretty much anything for the main image. If that data is bad (eg, the user uploaded a duff file, not corrupt transmission, which I agree is unlikely), then the device becomes bricked on reboot.
I wanted my code to be a little more diligent about checking the validity of the uploaded data to avoid this case; specifically a good bootloader but damaged main image.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One point I was just corrected on: TCP stream data isn't c'sum'd, so if you want to guarantee the data hasn't changed in flight from your server to the device you should use TLS(https)...you should do that, anyway, since OTW there is no security whatsoever.
Use TLS or signed images, and you get as good a guarantee as you're gonna get that data wasn't corrupted in flight. After that, if you hit bitrot you're bricked anyway with the current setup. The bootloader can't do anything in the case of CRC mismatch other infinite loop at that point.
What you're describing sounds like you want a backup firmware and for the bootloader to c'sum the primary before start (adds 2-3 seconds+++ to boot) and on fail jump to the backup and pray that wasn't corrupted. That's not supported now and not going to work w/o some serious work on the core. You might want to drop Arduino and use the plain SDK and rboot instead, if that's a requirement.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, TCP checksums or not, I'm not concerned at this stage about corrupt transmission. And yes, your description of the backup firmware would be the gold standard.
I guess I'm trying to get a 'good enough' solution, by having the device do the validation of an image (that it assumes has been received correctly), before submitting it as a replacement for the one and only real main image. Received an image? Checksums good? Please upgrade. Checksums bad? Please discard.
One could clearly make the argument that if there is no corruption, and the first part of the binary is a valid bootloader, then it's pretty unlikely the remaining data is not a valid image. There's no disputing that. But equally, the binary file format contains mechanisms (the segment checksums) that can give the paranoid programmer that extra feeling of warmth when validated. But since 3.0.0, they're broken. Best case, they can't be used; worst case, code that was already doing what I describe now starts rejecting otherwise valid images.
Aside: since my initial report, I've looked more closely at what this change actually did, and I agree it's perfectly sensible, and concur with the motivation. I just think it's a shame to have collateral damage as a result. One possible solution would be to have the CRC disregard the very final byte (where the checksum is), and then calculate that segment checksum after the CRC has been inserted.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addendum: how is it okay to stomp over program data anyway? I don't understand why putting the CRC where you now do doesn't break something (else).
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said, use TLS or signing. Either will give you 1000x better protection than a 1-byte checksum and ensure what goes into flash is what you sent.
You can also send in a PR to correct the calculation for .text, but you'd also want to redo eboot.c to actually look at it. And in case of failure, again I'm not sure what you can do other than brick given things as they are today.
It's not stomping on anything. The linker has reserved those locations already, see the .ld files. They're in a well-known address so the core can use it for the CRC check call (see the examples).
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's fair. Thanks.
07b4c09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, FYI, there is a built-in MD5 checksum if either your webserver or your app can provide it. Check the
.setMD5()
call out.