Как предотвратить переполнение буфера / массива?

Недавно я писал код для собственного протокола последовательной связи. Я использовал часть получаемых данных (8/16 бит), чтобы указать, насколько велик размер кадра. Основываясь на этих данных, я ожидаю, что нет данных для подражания. Я использую Crc, чтобы принять или отклонить кадр. Но я не смогу включить данные о длине кадра в Crc, так как на принимающей стороне я должен знать, сколько данных ожидать до обработки кадра.

Проблема, с которой я столкнулся, заключается в том, что иногда эти данные длины кадра повреждаются, и это обманывает получателя в получении такого количества байтов, тогда как размер принимающего массива намного меньше этого. Это повреждает много критических системных переменных, которые присутствуют в последовательных ячейках памяти.

Как предотвратить переполнение буфера? Мои мысли по этому поводу 1) Отклонить данные о длине кадра, если они выходят за пределы определенного значения. 2) используйте тип данных, который ограничивает максимальное число. Как использование короткого замыкания, которое ограничивает область индекса массива до 256 ячеек памяти, и создает буфер с 280 байтами. 3) выделить память в отдельном месте, чтобы она не влияла на критические системные переменные.

Одна вещь, которую я использовал для предотвращения зацикливания в приемном цикле - это использование тайм-аута Но я упустил из виду этот аспект проблемы. Мне кажется, что пришло время подтвердить и воспроизвести проблему, поскольку, таким образом, код является частью более крупного системного кода, и я здесь не эксперт.

Вообще, как безопасно решить этот тип вопросов?

Кроме того: каковы общие соображения или стандартные правила, которым необходимо следовать при использовании массива, чтобы предотвратить его переполнение?

2 ответа

Во -первых, проверьте на ошибки кадрирования, проверьте на ошибки четности

во-вторых, проверьте величину размера данных. если слишком большой или слишком маленький, отклонить весь блок данных

Есть много вещей, которые можно использовать, чтобы минимизировать эту проблему, однако не существует единого решения, подходящего для этого в целом. Вы должны принимать решения и понимать, что произойдет, если что-то пойдет не так, и ваша система сможет справиться с этим.

Вы должны выяснить, что именно подходит для вашей системы. Например, если вы никогда не ожидаете, что сообщение будет больше 256, тогда объявив размер вашего буфера как 0xFF, а индекс вашего буфера - как uint8_t, вы никогда не сможете превысить его, вставляя один байт за раз, так как индекс будет никогда не достигать 256 и переполняться обратно до 0. Обратной стороной этого является, конечно, если это произойдет, вы перезапишете некоторые полученные данные, но проверка crc должна выявить ошибку в большинстве случаев.

Другое, что вы можете сделать, это сравнить длину данных с максимальным значением буфера и не сохранять сообщение, если оно превышает ваш буфер. Таким образом, вы бы прямо отклонили любые сообщения, чья длина данных слишком велика и получена, но не храните данные, попадающие на ваш сайт. Очевидно, что если длина данных часто искажается, у вас будет много проблем с этим.

Честно говоря, лучший способ - переосмыслить свой протокол последовательной связи. Не похоже, что он принимает ошибки, с которыми вы сталкиваетесь, очень хорошо. Вы можете иметь синхронизирующие байты в начале и конце вашего сообщения, чтобы просто убедиться, что вы действительно получаете хорошие данные, и CRC всего сообщения без проблем, и определить максимальные размеры пакетов данных, которые будут передаваться по проводам, и сигнализировать, сколько пакетов должно быть быть принятым. Если протокол связи не очень хорош, вам нужно переосмыслить его снизу вверх.

Другие вопросы по тегам