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

Most versions of OTAImageProcessorImpl::SetBlock are broken #13393

Closed
bzbarsky-apple opened this issue Jan 8, 2022 · 6 comments · Fixed by #13778
Closed

Most versions of OTAImageProcessorImpl::SetBlock are broken #13393

bzbarsky-apple opened this issue Jan 8, 2022 · 6 comments · Fixed by #13778
Assignees
Labels
spec Mismatch between spec and implementation V1.0

Comments

@bzbarsky-apple
Copy link
Contributor

Problem

The K32W, Linux, and EFR32 implementations of OTAImageProcessorImpl::SetBlock all have the same problem, due to being copy/pasted from each other. If the blocks coming in are different sizes (which is very much allowed in bdx), then any block that's larger than the smallest preceding block will fail.

Specifically, CopySpanToMutableSpan, which is used in the function does the following:

  1. Ensures that the source span fits inside the target span.
  2. Copies the data.
  3. Sets the size of the target span to the size of the source span.

Step 3 is key. It means that mBlock will be the size of the smallest block seen so far.

The implementation on ESP32 does not have this problem, though it will do too much releasing/allocating because it does not keep track of the actual available space in mBlock, just of the space used by the last block copied into it.

Proposed Solution

Ideally, stop having multiple copies of this (clearly hard to get right) code. Have one copy, that we make correct and everyone uses.

Failing that, at least copy/paste the non-buggy version.

@bzbarsky-apple bzbarsky-apple added the spec Mismatch between spec and implementation label Jan 8, 2022
@bzbarsky-apple bzbarsky-apple changed the title Most version of OTAImageProcessorImpl::SetBlock are broken Most versions of OTAImageProcessorImpl::SetBlock are broken Jan 8, 2022
@selissia
Copy link
Contributor

Testing the fix for this is currently blocked by #13429

selissia added a commit to selissia/connectedhomeip that referenced this issue Jan 25, 2022
@selissia selissia assigned tima-q and unassigned doru91, selissia and carol-apple Jan 26, 2022
selissia added a commit that referenced this issue Jan 26, 2022
…13778)

* Implement the CancelImageUpdate() OTARequestor API

* Restyled by clang-format

* Add CancelImageUpdate() to OTARequestorInterface

* Add the override modifier

* Add UpdateCancelled() API to OTARequestorDriver

* Restyled by clang-format

* Fix a bug in SetBlock() where varied block size will kill the download

Issue: #13393

Co-authored-by: Restyled.io <[email protected]>
@bzbarsky-apple
Copy link
Contributor Author

Not fixed. Just fixed for Linux, still broken for Ameba, EFR32, qpg (this last fixed in #14388).

@selissia selissia assigned selissia and unassigned tima-q Jan 27, 2022
@selissia
Copy link
Contributor

selissia commented Jan 27, 2022

Not fixed. Just fixed for Linux, still broken for Ameba, EFR32, qpg (this last fixed in #14388).

Not sure how it got closed (did the CI close it because it was referenced in my PR?). If I did it, it certainly wasn't on purpose as at that time I was assigning it to QPG.
I'll follow up.

@bzbarsky-apple
Copy link
Contributor Author

Not sure how it got closed (did the CI close it because it was referenced in my PR?

Your PR said "fixes #issue-number", and github itself automatically closes issues when a PR that says that is merged.

selissia added a commit to selissia/connectedhomeip that referenced this issue Jan 28, 2022
…roject-chip#13778)

* Implement the CancelImageUpdate() OTARequestor API

* Restyled by clang-format

* Add CancelImageUpdate() to OTARequestorInterface

* Add the override modifier

* Add UpdateCancelled() API to OTARequestorDriver

* Restyled by clang-format

* Fix a bug in SetBlock() where varied block size will kill the download

Issue: project-chip#13393

Co-authored-by: Restyled.io <[email protected]>
@andy31415 andy31415 added v1_triage_split_6 V1.0 spec Mismatch between spec and implementation and removed V1.0 spec Mismatch between spec and implementation labels Jan 30, 2022
@selissia
Copy link
Contributor

selissia commented Feb 3, 2022

Not fixed. Just fixed for Linux, still broken for Ameba, EFR32, qpg (this last fixed in #14388).

@bzbarsky-apple: sorry I don't fully follow. The following is the implementation in EFR32 (Ameba's is similar). Is something still broken here? This is the fix I applied back in December.

// Store block data for HandleProcessBlock to access
CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block)
{
    if ((block.data() == nullptr) || block.empty())
    {
        return CHIP_NO_ERROR;
    }

    // Allocate memory for block data if we don't have enough already
    if (mBlock.size() < block.size())
    {
        ReleaseBlock();

        mBlock = MutableByteSpan(static_cast<uint8_t *>(chip::Platform::MemoryAlloc(block.size())), block.size());
        if (mBlock.data() == nullptr)
        {
            return CHIP_ERROR_NO_MEMORY;
        }
    }

    // Store the actual block data
    CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format());
        return err;
    }

    return CHIP_NO_ERROR;
}

@bzbarsky-apple
Copy link
Contributor Author

I am not sure why I said "EFR32"... Ameba was fixed a few days ago (after my comment).

I just checked all the impls, and they look good now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec Mismatch between spec and implementation V1.0
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants