Lecture hors limites dans FrameDecoder::payload()
Erreur mémoire · heap-buffer-overflow, lecture de 512 octets
src/codec/frame_decoder.cpp:88
Explication
payload() lit la longueur du contenu dans l’en-tête de la trame, puis copie ce nombre d’octets sans le comparer à la taille réellement reçue. Une trame courte qui annonce un long contenu fait lire la mémoire au-delà du tampon.
Pourquoi « Atteint par une vraie entrée »
Le test appelle FrameDecoder::decode(), le point d’entrée public, avec une trame de 8 octets : ce qu’un émetteur quelconque pourrait envoyer.
Code concerné
std::vector<uint8_t> FrameDecoder::payload(const uint8_t* data,
size_t size) const {
if (size < kHeaderSize) {
return {};
}
const uint16_t len = read_u16_le(data + 2);
std::vector<uint8_t> out(len);
std::memcpy(out.data(), data + kHeaderSize, len);
↑ len vient de l’en-tête et n’est jamais comparé à size
return out;
}
Test écrit par VaultLens
// Passe par l'API publique, comme une trame reçue.
#include "codec/frame_decoder.h"
#include <cstdint>
#include <vector>
int main() {
// 8 octets reçus, l'en-tête en annonce 512.
std::vector<uint8_t> frame = {0xA5, 0x01, 0x00, 0x02,
0x10, 0x20, 0x30, 0x40};
codec::FrameDecoder decoder;
decoder.decode(frame.data(), frame.size());
return 0;
}
Commande lancée
C:\analyse\projet> cmake --build build --config Debug --target frame_decoder_payload_overflow
C:\analyse\projet> build\vaultlens_tests\Debug\frame_decoder_payload_overflow.exe
Rejeu
La même commande, relancée, produit le même échec à la même ligne. Vous pouvez la relancer vous-même.
Sortie qui échoue (extrait)
=================================================================
==7316==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x11f0a2be0018 at pc 0x7ff7d1c2b3e4 bp 0x00a3c7cff1a0 sp 0x00a3c7cff1a8
READ of size 512 at 0x11f0a2be0018 thread T0
#0 0x7ff7d1c2b3e3 in __asan_memcpy
#1 0x7ff7d1c1a4f6 in codec::FrameDecoder::payload C:\analyse\projet\src\codec\frame_decoder.cpp:88
#2 0x7ff7d1c19d01 in codec::FrameDecoder::decode C:\analyse\projet\src\codec\frame_decoder.cpp:41
#3 0x7ff7d1c11085 in main C:\analyse\projet\vaultlens_tests\frame_decoder_payload_overflow.cpp:11
0x11f0a2be0018 is located 0 bytes after 8-byte region [0x11f0a2be0010,0x11f0a2be0018)
allocated by thread T0 here:
#0 0x7ff7d1c2c8a1 in operator new
#1 0x7ff7d1c1104b in main C:\analyse\projet\vaultlens_tests\frame_decoder_payload_overflow.cpp:8
SUMMARY: AddressSanitizer: heap-buffer-overflow C:\analyse\projet\src\codec\frame_decoder.cpp:88 in codec::FrameDecoder::payload
…