Skip to content

Conversation

@andre-comet
Copy link

When working with an Ethercat CoE slave that would occasionally send an invalid packet with mailbox size 0 during segmented transfer, SOEM causes a hard fault (access violation).

While the root cause is a bug in the slave, SOEM should handle it and signal an error instead of crashing due to an access violation.

The issue is caused in line 244 in the calculation of Framedatasize:
Framedatasize = etohs(aSDOp->MbxHeader.length) - 3
If MbxHeader.length is zero, the UINT16 value wraps to 65533 (0 - 3 = 65535 - 2). Faulty Framedatasize of 65533 is then passed as size argument to memcpy, causing the access violation

Invalid packet:
image

Framedatasize is 65533 when passed as size parameter to memcpy in line 257 of ethercatcoe.c:
image

My change simply checks if the -3 calculation would cause a wrap of the UINT. If it would, ecx_packeterror() is called.

I tested this change with the pysoem wrapper on windows and it now throws a packet error exception which can be handled, instead of causing an access violation which crashed the Ethercat master entirely.

@andre-comet andre-comet force-pushed the fix-zero-mailbox-length-access-violation branch 2 times, most recently from bdf57ad to 164bc12 Compare November 29, 2022 10:46
@andre-comet andre-comet force-pushed the fix-zero-mailbox-length-access-violation branch from 164bc12 to 6a5babf Compare November 29, 2022 10:47
@andre-comet andre-comet reopened this Nov 29, 2022
@andre-comet andre-comet force-pushed the fix-zero-mailbox-length-access-violation branch from 01021dd to 2ef4d15 Compare November 29, 2022 10:56
@andre-comet andre-comet marked this pull request as ready for review November 29, 2022 10:57
@andre-comet
Copy link
Author

andre-comet commented Dec 16, 2022

@ArthurKetels: this needs approval again after bringing it up to date with OpenEtherCATsociety:master

Copy link
Contributor

@ArthurKetels ArthurKetels 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 catching this bug. The solution is however not enough to fix all cases.
Example 1: MbxHeader.Length - 3 > buffer size
Example 2: More segmented transfers than buffer size. Each segment being perfectly valid.
The solution should be that each memcpy in the segmented transfer is checked for bounds before executing.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants