From f50d9f5688e7b571ee9437546711049e0171988a Mon Sep 17 00:00:00 2001 From: Dinyar Rabady <dinyar.rabady@cern.ch> Date: Mon, 28 Nov 2022 15:46:36 +0100 Subject: [PATCH] Add asserts to ensure we don't leave valid memory space --- src/processor.cc | 23 ++++++++++++++++------- src/processor.h | 4 ++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/processor.cc b/src/processor.cc index ac63156e..bd1ba6b7 100644 --- a/src/processor.cc +++ b/src/processor.cc @@ -6,6 +6,7 @@ #include <cmath> #include <vector> #include <algorithm> +#include <cassert> // Definition of the static member stats StreamProcessor::Statistics StreamProcessor::stats; @@ -64,7 +65,7 @@ bool StreamProcessor::CheckFrameMultBlock(size_t inputSize){ bool StreamProcessor::GetTrailer(Slice& input, char*& rd_ptr) { rd_ptr += 32; // +32 to account for orbit header - while ( rd_ptr != input.end()){ + while ( rd_ptr + sizeof(orbit_trailer) - 1 <= input.end() ) { orbit_trailer* ot = reinterpret_cast<orbit_trailer*>(rd_ptr); if (ot->beefdead[0]==constants::beefdead){ // found orbit trailer return true; @@ -87,7 +88,7 @@ inline std::pair<uint32_t, bool> StreamProcessor::ProcessOrbitHeader(char* rd_pt } // Goes through orbit worth of data and fills the output memory with the calo data corresponding to the non-empty bunchcrossings, as marked in bx_vect -StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitCalo(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr){ +StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitCalo(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr, char* rd_end_ptr, char* wr_end_ptr){ std::pair<uint32_t, bool> orbit_header = std::pair<uint32_t, bool> {ProcessOrbitHeader(rd_ptr)};//.second is the warning test enable bit rd_ptr += 32; // +32 to account for orbit header uint32_t orbit = uint32_t{orbit_header.first} - 1; // Starting with orbit number one lower than what is in the header because the "link orbit" contains a few BXs of the previous orbit @@ -117,9 +118,11 @@ StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitCalo(orbit_trailer* if((trailer->bx_map[word] & (1 << bit)) == 0) { continue; // If the bit is zero that BX was empty and we continue. } + assert(rd_ptr + sizeof(blockCalo) - 1 <= rd_end_ptr); ++filled_bxs; blockCalo *bl = reinterpret_cast<blockCalo*>(rd_ptr); if (bl->calo0[0]==constants::beefdead){break;} // orbit trailer has been reached, end of orbit data + assert(wr_ptr + (3 + 8*7)*4 - 1 <= wr_end_ptr); uint32_t header = uint32_t{orbit_header.second}; //header can be added to later memcpy(wr_ptr,(char*)&header,4); wr_ptr+=4; memcpy(wr_ptr,(char*)&bx,4); wr_ptr+=4; @@ -152,6 +155,7 @@ uint32_t StreamProcessor::FillBril(char* rd_ptr, char* wr_ptr, char* end_ptr){ //BrilHistoQueue<std::array<uint32_t, constants::NBXPerOrbit + constants::NFramesInHistoHeader>> BrilQueue; while ( (rd_ptr != end_ptr) && (histo_i < NHistosPerPacket)){ + assert(rd_ptr + sizeof(brilFrame) - 1 <= end_ptr); brilFrame *fr = reinterpret_cast<brilFrame*>(rd_ptr); if (fr->word == constants::bril_header){ @@ -185,7 +189,7 @@ uint32_t StreamProcessor::FillBril(char* rd_ptr, char* wr_ptr, char* end_ptr){ // Goes through orbit worth of data and fills the output memory with the muons corresponding to the non-empty bunchcrossings, as marked in bx_vect -StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitMuon(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr){ +StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitMuon(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr, char* rd_end_ptr, char* wr_end_ptr){ std::pair<uint32_t, bool> orbit_header = std::pair<uint32_t, bool>{ProcessOrbitHeader(rd_ptr)};//.second is the warning test enable bit rd_ptr += 32; // +32 to account for orbit header uint32_t orbit = uint32_t{orbit_header.first} - 1; // Starting with orbit number one lower than what is in the header because the "link orbit" contains a few BXs of the previous orbit @@ -215,9 +219,11 @@ StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitMuon(orbit_trailer* if((trailer->bx_map[word] & (1 << bit)) == 0) { continue; // If the bit is zero that BX was empty and we continue. } + assert(rd_ptr + sizeof(blockMuon) - 1 <= rd_end_ptr); ++filled_bxs; blockMuon *bl = reinterpret_cast<blockMuon*>(rd_ptr); if (bl->orbit[0]==constants::beefdead){ break; } // orbit trailer has been reached, end of orbit data + assert(wr_ptr + (3 + 2*8*3)*4 - 1 <= wr_end_ptr); // Assuming the maximum size a decoded muon block can use. int mAcount = 0; int mBcount = 0; bool AblocksOn[8]; @@ -292,7 +298,8 @@ void StreamProcessor::process(Slice& input, Slice& out) char* rd_ptr = input.begin(); char* wr_ptr = out.begin(); - char* end_ptr = input.end(); + char* rd_end_ptr = input.end(); + char* wr_end_ptr = out.begin() + out.avail(); uint32_t counts = 0; bool endofpacket = false; uint32_t orbit_per_packet_count = 0; @@ -305,7 +312,7 @@ void StreamProcessor::process(Slice& input, Slice& out) return; } if (processorType == ProcessorType::BRIL){ - counts = FillBril(rd_ptr, wr_ptr, end_ptr); + counts = FillBril(rd_ptr, wr_ptr, rd_end_ptr); out.set_end(out.begin() + counts); out.set_counts(counts); return; @@ -323,12 +330,12 @@ void StreamProcessor::process(Slice& input, Slice& out) } orbit_trailer* trailer = reinterpret_cast<orbit_trailer*>(trailer_ptr); if (processorType == ProcessorType::GMT) { - meta = FillOrbitMuon(trailer, rd_ptr, wr_ptr); + meta = FillOrbitMuon(trailer, rd_ptr, wr_ptr, rd_end_ptr, wr_end_ptr); orbitCount = meta.counts; ++orbit_per_packet_count; wr_ptr+= meta.counts*12 + 12*meta.filled_bxs; // 12 bytes for each muon/count then 12 bytes for each bx header } else if (processorType == ProcessorType::CALO){ - meta = FillOrbitCalo(trailer, rd_ptr, wr_ptr); + meta = FillOrbitCalo(trailer, rd_ptr, wr_ptr, rd_end_ptr, wr_end_ptr); orbitCount = meta.counts; ++orbit_per_packet_count; // size of calo packet is 4bytes*(8links*7dataWords + 3headerWords)=236 bytes @@ -339,6 +346,8 @@ void StreamProcessor::process(Slice& input, Slice& out) throw std::invalid_argument("ERROR: PROCESSOR_TYPE NOT RECOGNISED"); } rd_ptr+= 32 + meta.filled_bxs*sizeof(blockMuon) + constants::orbit_trailer_size; // 32 for orbit header, + nBXs + orbit trailer + assert(wr_ptr <= wr_end_ptr); + assert(rd_ptr <= rd_end_ptr); counts += orbitCount; if (firstOrbit){ out.set_firstOrbitN(meta.orbit); diff --git a/src/processor.h b/src/processor.h index c2a42e7a..b17f5ff7 100644 --- a/src/processor.h +++ b/src/processor.h @@ -33,8 +33,8 @@ private: bool CheckFrameMultBlock(size_t inputSize); bool GetTrailer(Slice& input, char*& rd_ptr); inline std::pair<uint32_t, bool> ProcessOrbitHeader(char* rd_ptr); - fillOrbitMetadata FillOrbitMuon(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr); - fillOrbitMetadata FillOrbitCalo(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr); + fillOrbitMetadata FillOrbitMuon(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr, char* rd_end_ptr, char* wr_end_ptr); + fillOrbitMetadata FillOrbitCalo(orbit_trailer* trailer, char* rd_ptr, char* wr_ptr, char* rd_end_ptr, char* wr_end_ptr); uint32_t FillBril(char* rd_ptr, char* wr_ptr, char* end_ptr); size_t max_size; uint64_t nbPackets; -- GitLab