After seeing many similar threads, I can not properly resolve this error message from Valgrind (memcheck):
==397018== Invalid read of size 1
==397018== at 0x527689D: JUMP_TO_L3_EXT_HEADER(unsigned char const*, unsigned char, unsigned long) (ip_proto.h:628)
==397018== by 0x5276A2B: JUMP_TO_L3_FRAG_HEADER(unsigned char const*, unsigned long) (ip_proto.h:654)
==397018== by 0x5276B1D: GET_L3_FRAG_INFO_IPV6(unsigned char const*, unsigned int&, unsigned short&, unsigned char&, unsigned char&, unsigned long, unsigned char*) (ip_proto.h:668)
==397018== by 0x5277744: packetinfo::L3PacketHandler::fill(unsigned char const*, unsigned int) (L3PacketHandler.h:170)
==397018== by 0x5277CA4: packetinfo::PacketInfo::fill(unsigned char const*, unsigned int, bool) (PacketInfo.h:292)
==397018== by 0x5277E68: cdpi::protoengine::PacketInfoCache::fill(unsigned char*, unsigned int, bool) (PacketInfoCache.h:73)
==397018== by 0x51621D3: cdpi::protoengine::ProtoEngine::initPacketPath(bool, unsigned char*, unsigned int, unsigned int) (ProtoEngine.cc:3412)
==397018== by 0x5224436: cdpi::FlowManager::FlowManagerPriv::getFlow(bool, unsigned char*, unsigned int, unsigned int, generic_addr const&, cdpi::ClassificationResult&, cdpi::L4Data*, cdpi::User*) (FlowManagerPriv.cc:205)
==397018== by 0x5223D9E: cdpi::FlowManager::getFlow(bool, unsigned char*, unsigned int, unsigned int, generic_addr const&, cdpi::ClassificationResult&, cdpi::L4Data*, cdpi::User*) (FlowManager.cc:41)
==397018== by 0x61C4B7: dpisim::CDPIFlavour::processPDUs(dpisim::DPIsimPolicyDecisor*, dpisim::DPIsimPacket&, dpisim::DPIsimPacketResult&, cdpi::ClassificationResult&, cdpi::AnalyzerContext&, int, dpisim::DPIsimUser&) (CDPIFlavour.cc:280)
==397018== by 0x61C224: dpisim::CDPIFlavour::processPacket(dpisim::DPIsimPacket&, dpisim::DPIsimPacketResult&, dpisim::DPIsimUser&) (CDPIFlavour.cc:248)
==397018== by 0x614D46: dpisim::DPIAdapter::processPacket(dpisim::DPIsimPacket&, dpisim::DPIsimPacketResult&, dpisim::DPIsimUser&) (DPIAdapter.cc:282)
==397018== Address 0x7bdc5ef is 7 bytes after a block of size 56 alloc'd
==397018== at 0x4A08982: operator new[](unsigned long) (vg_replace_malloc.c:385)
==397018== by 0x5BAEAD: dpisim::DPIsimPacket::initialize(pcap_pkthdr const*, unsigned char const*, unsigned int) (DPIsimPacket.cc:215)
==397018== by 0x5BA45F: dpisim::DPIsimPacket::DPIsimPacket(pcap_pkthdr const*, unsigned char const*, unsigned int) (DPIsimPacket.cc:42)
==397018== by 0x5DF4A6: dpisim::DPIsimPacketManager::manipulatePacket(unsigned int, pcap_pkthdr*, unsigned char const*, unsigned int) (DPIsimPacketManager.cc:102)
==397018== by 0x5ADEC6: dpisim::DPIsimTracePcap::run() (DPIsimTracePcap.cc:134)
==397018== by 0x5DEAC6: boost::_mfi::mf0<void, dpisim::DPIsimTrace>::operator()(dpisim::DPIsimTrace*) const (mem_fn_template.hpp:49)
==397018== by 0x5DE969: void boost::_bi::list1<boost::_bi::value<dpisim::DPIsimTrace*> >::operator()<boost::_mfi::mf0<void, dpisim::DPIsimTrace>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, dpisim::DPIsimTrace>&, boost::_bi::list0&, int) (bind.hpp:255)
==397018== by 0x5DE89C: boost::_bi::bind_t<void, boost::_mfi::mf0<void, dpisim::DPIsimTrace>, boost::_bi::list1<boost::_bi::value<dpisim::DPIsimTrace*> > >::operator()() (bind_template.hpp:20)
==397018== by 0x5DE817: boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, dpisim::DPIsimTrace>, boost::_bi::list1<boost::_bi::value<dpisim::DPIsimTrace*> > > >::run() (thread.hpp:116)
==397018== by 0x6089D49: thread_proxy (in /lab/dpi/building-deps/boost/boost_1_59_0/lib/libboost_thread.so.1.59.0)
==397018== by 0x3D45807AA0: start_thread (in /lib64/libpthread-2.12.so)
==397018== by 0x3D454E893C: clone (in /lib64/libc-2.12.so)
The code that causes the error is the line indicated in the comment:
inline const unsigned char* JUMP_TO_L3_EXT_HEADER(const unsigned char* packet, uint8_t extHeader,size_t packetlen = 0) {
if(VERSION_IPv4 == IP_VERSION(packet)) {
return packet;
} else {
uint8_t current_header = IPPROTO_IPV6;
// Check packetlen
uint32_t size = 0;
while((extHeader!= current_header && (IPPROTO_IPV6 == current_header || IPPROTO_FRAGMENT == current_header ||
IPPROTO_HOPOPTS == current_header || IPPROTO_ROUTING == current_header ||
IPPROTO_DSTOPTS == current_header || IPPROTO_AH == current_header))) {
if (packetlen!=0 && size>packetlen)
{
// Error calculating extension header size. Exit
return NULL;
}
uint8_t next_header=IPPROTO_IPV6;
switch(current_header) {
case IPPROTO_IPV6:
next_header = ((const ip6_hdr*)packet)->ip6_ctlun.ip6_un1.ip6_un1_nxt;
packet += sizeof(const ip6_hdr);
size += sizeof(const ip6_hdr);
break;
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
/* All these headers have the first 16 bits equal, so we can group them */
next_header = ((const ip6_ext*)packet)->ip6e_nxt;
packet += 8 + ((((const ip6_ext*)packet)->ip6e_len)<<3); /* +1 because according to RFC size does not include the first 8 bytes */
size += 8 + ((((const ip6_ext*)packet)->ip6e_len)<<3);//AQUÍ INDICA VALGRIND EL ACCESO INDEBIDO!!!
break;
case IPPROTO_FRAGMENT:
next_header = ((const ip6_ext*)packet)->ip6e_nxt;
packet += sizeof(ip6_frag);
size += sizeof(ip6_frag);
break;
case IPPROTO_AH:
/* Authentication header does include the size in a different format that the rest of headers ...
Very smart thing to do in a standard!
The size is a 16 bit network-order word, which give you the number of 4-bytes words in size, minus 8*/
next_header = ((const ip6_ext*)packet)->ip6e_nxt;
packet += 8 + ((be16toh( ((*(packet+1))<<8) + *(packet+2)))<<2);
size += 8 + ((be16toh( ((*(packet+1))<<8) + *(packet+2)))<<2);
break;
}
current_header = next_header;
}
return (extHeader == current_header) ? packet : NULL;
}
}
I put a printf to try to detect the fault. Give the following output:
size=48, ip6e_len=0, ip6e_len<<3=0
Any suggestions will be well accepted.