简体   繁体   English

如何防止缓冲区溢出/阵列溢出?

[英]How to prevent Buffer overflow / array overflow?

I was recently writing code for a custom serial communication protocol. 我最近在编写自定义串行通信协议的代码。 What I did was, I used a part(8/16 bit) of the receiving data to denote how big the frame size is. 我所做的是,我使用接收数据的一部分(8/16位)来表示帧大小有多大。 Based on this data I expect that no of data to follow. 在此基础上的数据我希望不会有数据可循。 I use Crc to accept or reject a frame. 我使用Crc接受或拒绝一个帧。 But I won't be able to include the frame length data in the Crc, since on the receiving end I should know how much data to expect, before processing a frame. 但是我无法在Crc中包含帧长度数据,因为在接收端我应该知道在处理帧之前需要多少数据。

The issue that I faced is, occasionally this frame length data gets corrupted and it fools the receiver into receiving that many bytes, whereas the receiving array size is much lesser than that. 我遇到的问题是,偶尔这个帧长度数据被破坏并且它使接收器接收到那么多字节,而接收阵列的大小要小得多。 This corrupts a lot of critical system variables that is present in the consecutive memory locations. 这破坏了连续存储器位置中存在的许多关键系统变量。

How do I prevent the buffer overflow from happening? 如何防止缓冲区溢出? My thoughts on this 1) Reject the framelength data if it goes beyond a certain value. 我对此的看法1)如果帧长度数据超过某个值,则拒绝它。 2) use a datatype that limits the max no. 2)使用限制最大值的数据类型。 Like using a short which limits the scope of the array index to 256 memory locations, and create a buffer with 280 bytes. 就像使用short将数组索引的范围限制为256个内存位置,并创建一个280字节的缓冲区。 3) allocate memory in a separate location, so that it doesn't affect the critical system variables. 3)在一个单独的位置分配内存,这样它就不会影响关键的系统变量。

One thing I used to prevent getting stuck in the receiving loop is by using a timeout. 我用来阻止卡在接收循环中的一件事是使用超时。 But I overlooked this aspect of the issue. 但我忽略了这个问题的这个方面。 It look me lot if time to confirm and reproduce the issue, since thus code is part of a larger system code, and I'm not an expert here. 如果有时间来确认和重现问题,那么看起来很多,因为代码是更大的系统代码的一部分,我不是这里的专家。

Generally how to safely handle this type of issues? 一般如何安全地处理这类问题?

Also: what are general considerations or standard practices to follow when using an array, to prevent it from overflowing? 另外:使用数组时要遵循的一般注意事项或标准做法是什么,以防止它溢出?

There's a lot of things that can be used to minimize this issue, however there is no one size fit's all solution for this in general. 有很多东西可以用来最小化这个问题,但是没有一个尺寸适合这一般的解决方案。 You have to make decisions and understand what happens if something goes wrong and have your system be able to handle it. 您必须做出决定并了解如果出现问题并使您的系统能够处理它会发生什么。

You have to figure out what exactly fits best for your system. 你必须弄清楚什么最适合你的系统。 For example if you never expect a message to be greater than 256 then declaring the size of your buffer as 0xFF and the index of your buffer as a uint8_t you'll never be able to exceed it inserting one byte at a time as the index will never reach 256 and overflow back to 0. The downside of that is of course if this does happen, you overwrite some of the data received, but the crc check should reveal error in most cases. 例如,如果您从未期望消息大于256,那么将缓冲区的大小声明为0xFF,将缓冲区的索引声明为uint8_t,您将永远无法超过它一次插入一个字节作为索引永远不会达到256并溢出回0.当然,如果发生这种情况,你会覆盖一些收到的数据,但crc检查应该在大多数情况下显示错误。

Another thing you can do is compare the data length to the buffer max and not store the message if it exceeds your buffer. 您可以做的另一件事是将数据长度与缓冲区最大值进行比较,如果超出缓冲区则不存储消息。 So you would outright reject any messages who's data length is too big and received, but not store data coming across. 因此,您可以直接拒绝任何数据长度过大且收到的消息,但不会存储数据。 Obviously if the data length comes in corrupted often, you'll have a lot of issues with this. 显然,如果数据长度经常损坏,那么你会遇到很多问题。

To be honest, the best method is to rethink your custom serial communication protocol. 说实话,最好的方法是重新考虑您的自定义串行通信协议。 It doesn't sound like it takes the errors you are encountering very well. 这听起来不像是你遇到的错误很好。 You can have sync bytes at the beginning and end of your message to just make sure that you are actually receiving good data and CRC the entire message no problem and define max data packet sizes that will go across the wire and signal how many packets are to be received. 您可以在消息的开头和结尾处同步字节,以确保您实际上正在接收良好的数据和CRC整个消息没有问题,并定义将通过线路的最大数据包大小并发信号通知有多少数据包收到。 If the communication protocol isn't very good then you have to rethink it from the bottom up. 如果通信协议不是很好,那么你必须从下往上重新考虑它。

first, check for framing errors, check for parity errors 首先,检查帧错误,检查奇偶校验错误

second, check the magnitude of the data size. 第二,检查数据大小的大小。 if too big or too small, reject the whole data block 如果太大或太小,拒绝整个数据块

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM