【问题标题】:How to prevent Buffer overflow / array overflow?如何防止缓冲区溢出/数组溢出?
【发布时间】:2016-04-09 18:43:32
【问题描述】:

我最近正在为自定义串行通信协议编写代码。我所做的是,我使用了接收数据的一部分(8/16 位)来表示帧大小有多大。根据这些数据,我预计 没有数据可以遵循。我使用 Crc 来接受或拒绝一个框架。但我无法在 Crc 中包含 帧长度 数据,因为在接收端我应该知道在处理帧之前需要多少数据。

我面临的问题是,有时这个帧长度数据会被破坏,它会欺骗接收器接收那么多字节,而接收数组的大小要小得多。这会破坏连续内存位置中存在的许多关键系统变量。

如何防止缓冲区溢出? 我对此的看法 1) 如果 framelength 数据超过某个值,则拒绝它。 2)使用限制最大数量的数据类型。就像使用 short 将数组索引的范围限制为 256 个内存位置,并创建一个 280 字节的缓冲区。 3) 在单独的位置分配内存,这样就不会影响关键的系统变量。

我用来防止卡在接收循环中的一件事是使用超时。但我忽略了这个问题。 如果有时间确认和重现该问题,我会觉得很多,因为代码是更大系统代码的一部分,我不是这里的专家。

一般如何安全处理此类问题?

另外:使用数组时应遵循哪些一般注意事项或标准做法,以防止其溢出?

【问题讨论】:

  • 发送缓冲区长度两次(可能第二次倒置)。如果匹配就OK了。
  • 您可以通过选择包含奇偶校验位的串行协议来改进错误检测。
  • 这就是简单的解决方案。另一种解决方案是发送一个固定大小的标头,该标头本身具有 CRC 或某种前向纠错功能。
  • 我的意思是,即使客户端收到损坏的帧长度,也没有任何理由可以欺骗客户端进入缓冲区溢出。客户端知道它的缓冲区有多大,它可以完全控制它在哪里存储多少字节。
  • 在任何情况下都没有 100% 万无一失的错误检测机制。这都是一个开销很大的问题——无论是在数据方面还是在计算方面——您想要投资于错误检测,以及您希望数据以无法检测到的方式损坏的可能性有多大。跨度>

标签: c arrays embedded exception-safety memory-safety


【解决方案1】:

有很多方法可以用来尽量减少这个问题,但是一般来说,没有一种适合的解决方案。您必须做出决定并了解如果出现问题会发生什么,并让您的系统能够处理它。

您必须弄清楚什么最适合您的系统。例如,如果您从不期望消息大于 256,那么将缓冲区的大小声明为 0xFF 并将缓冲区的索引声明为 uint8_t 您将永远无法超过它一次插入一个字节,因为索引将永远不会达到 256 并溢出回 0。当然,如果确实发生这种情况,您会覆盖收到的一些数据,但在大多数情况下,crc 检查应该会显示错误。

您可以做的另一件事是将数据长度与缓冲区最大值进行比较,如果消息超出缓冲区,则不存储消息。因此,您将彻底拒绝任何数据长度过大且已收到但不存储遇到的数据的消息。显然,如果数据长度经常损坏,您将遇到很多问题。

说实话,最好的方法是重新考虑您的自定义串行通信协议。听起来您遇到的错误并不好。您可以在消息的开头和结尾设置同步字节,以确保您实际上收到了良好的数据,并对整个消息进行 CRC 校验,并定义将通过线路的最大数据包大小并指示要发送多少个数据包被接收。如果通信协议不是很好,那么您必须自下而上重新考虑。

【讨论】:

  • 我会尝试使用unit8。我已经在帧的开头使用了同步字节。只有在我检测到同步字节之后,我才会得到这个帧大小数据。似乎数据损坏发生在帧中的随机字节中,而其他字节似乎很好。
【解决方案2】:

首先,检查帧错误,检查奇偶校验错误

其次,检查数据大小的大小。如果太大或太小,则拒绝整个数据块

【讨论】:

  • 我正在使用标头来检测帧的开始和位定位。作为配对,我没有使用 UART,所以在 SW 中计算将是一个开销。检查框架的大小并拒绝可能会起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
相关资源
最近更新 更多