Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix HalModuleParser.parsePrefix() when parsing valid compressed binaries #41

Merged

Conversation

avtolstoy
Copy link
Member

Current version of binary-version-reader may provide invalid module prefix for valid compressed modules due to hardware platform-specific heuristics.

This causes errors in Device Service and disables compression and module combination when performing OTAs:

RangeError: Invalid size of the module data\
 at combineModules (/usr/src/app/node_modules/binary-version-reader/lib/moduleEncoding.js:405:10)\
 at runMicrotasks (<anonymous>)\
 at processTicksAndRejections (internal/process/task_queues.js:93:5)\
 at async Flash._combineModuleBinaries (/usr/src/app/lib/behaviors/Flash.js:475:18)\
 at async Flash._preprocessModuleBinary (/usr/src/app/lib/behaviors/Flash.js:394:20)\
 at async Flash.flash (/usr/src/app/lib/behaviors/Flash.js:130:12)"

The following binary after compression will not be correctly parsed:
tracker-system-part1@3.1.0-alpha.2.bin

Compressed:
compressed_tracker-system-part1@3.1.0-alpha.2.bin

 CRC is ok (35df8d60)
 Compiled for unknown platform (ID: 19388)
 This is an unknown module number 182 at version 8993
 It depends on undefined number 20 at version 62570

This should instead be:

 CRC is ok (35df8d60)
 Compiled for tracker
 This is a system module number 1 at version 3101
 It depends on a bootloader number 0 at version 1006
 It also depends on a network coprocessor (NCP) module number 0 at version 7

@avtolstoy avtolstoy added the bug label May 25, 2021
@avtolstoy avtolstoy requested review from wraithan and sergeuz May 25, 2021 23:01
avtolstoy added 3 commits May 26, 2021 07:37
… causes HalModuleParser.parsePrefix() to parse the module prefix at incorrect location
@avtolstoy avtolstoy force-pushed the feature/ch80114/fix-halmoduleparser-parseprefix-when-parsing branch from 83f985b to 37764d1 Compare May 26, 2021 00:37
Copy link

@wraithan wraithan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the code looks good, reads a lot better and I appreciate the code clean up you've done.

I'm a bit 🤔 about the strict option to _validateModulePrefix and would like to discuss before approval.

lib/HalModuleParser.js Show resolved Hide resolved
0x184, // Gen 2
0xC0, // Bluez
0x10C, // Core
];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this reads far better I really like this cleanup

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I was going to suggest adding a zero offset to the list of preferred ones, but then I noticed that it's actually there, it just didn't deserve its own line in the array definition. I'd add a comment that the module header typically starts at 0 offset if it's a user part or other non-system/bootloader module.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved 0 to a separate line and added an additional comment.

@avtolstoy avtolstoy requested a review from wraithan May 27, 2021 06:29
Copy link
Member

@sergeuz sergeuz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What an awesome PR 👍

const expectedSize = endAddr - startAddr + 4 /* CRC-32 */;
if (fileBuffer.length < expectedSize) {
return result;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment why we don't want to fail immediately if the file is larger than what is specified in the module header would be helpful here (padded/combined modules).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const allFlags = Object.values(ModuleInfo.Flags).reduce((a, b) => (a | b), 0);
if ((prefixInfo.moduleFlags & (~allFlags)) === 0) {
result.score++;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-zero version numbers (of the module itself and its dependencies) can be another 0.25 score points 🙂 Also, the fact that start/end addresses are in the internal flash (where applicable) that was checked in the old code was a good indication that we're dealing with a valid module, IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the fact that start/end addresses are in the internal flash (where applicable) that was checked in the old code was a good indication that we're dealing with a valid module, IMO.

I think we should be able to get away without these kinds of platform-specific checks and probably should if we can. It's also impossible to implement such checks properly for Gen 3 platforms as addresses in the internal flash are generic 0 to 1MB.

Non-zero version numbers (of the module itself and its dependencies) can be another 0.25 score points 🙂

As discussed in Slack, let's keep things as-is. Given all the other checks it's anyway highly likely that the versions will not be zero.

(userModuleStartAddy.indexOf("20") == 0); // stack is located in ram at 0x2000000

if (isCore) {
return 0x10C;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes. Thank you so much for doing this.

0x184, // Gen 2
0xC0, // Bluez
0x10C, // Core
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I was going to suggest adding a zero offset to the list of preferred ones, but then I noticed that it's actually there, it just didn't deserve its own line in the array definition. I'd add a comment that the module header typically starts at 0 offset if it's a user part or other non-system/bootloader module.

@@ -23,9 +23,9 @@ var when = require('when');
var pipeline = require('when/pipeline');
var utilities = require('./utilities.js');
var buffers = require('h5.buffers');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module is no longer used in this file. I'd also check if we even need this dependency at all, given the changes in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, no longer required. Removed the dependency.

Copy link

@wraithan wraithan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, looks great

@avtolstoy avtolstoy merged commit 94e26d9 into master May 27, 2021
@avtolstoy avtolstoy deleted the feature/ch80114/fix-halmoduleparser-parseprefix-when-parsing branch May 27, 2021 14:45
avtolstoy added a commit to particle-iot/particle-cli that referenced this pull request May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants