>Submitter-Id:  net
>Originator:    bert hubert ([EMAIL PROTECTED])
>Organization:  PowerDNS
>Confidential:  no
>Synopsis:      When reserving a string to become smaller, program crashes
>Severity:      serious
>Priority:      medium
>Category:      libstdc++
>Class:         wrong-code
>Release:       3.0.2 20010922 (Debian prerelease) (Debian testing/unstable)
>Environment:
System: Linux hubert 2.4.10 #1 Sun Sep 23 21:14:45 CEST 2001 i686 unknown
Architecture: i686

        
host: i386-pc-linux-gnu
build: i386-pc-linux-gnu
target: i386-pc-linux-gnu
configured with: ../src/configure -v 
--enable-languages=c,c++,java,f77,proto,objc --prefix=/usr 
--infodir=/share/info --mandir=/share/man --enable-shared --with-gnu-as 
--with-gnu-ld --with-system-zlib --enable-long-long --enable-nls 
--without-included-gettext --disable-checking --enable-threads=posix 
--enable-java-gc=boehm --with-cpp-install-dir=bin --enable-objc-gc i386-linux
>Description:
Snippet of code:

/** convenience function for creating a reply packet from a question packet.
Do not forget to delete it after use! */
DNSPacket *DNSPacket::replyPacket() const
{
  DNSPacket *r=new DNSPacket;
  r->setRemote(&remote);
  r->setAnswer(true);  // this implies the allocation of the header
  r->setA(true); // and we are authoritative
  r->setRA(0); // no recursion available
  r->setRD(d.rd); // if you wanted to recurse, answer will say you wanted it
(we don't do it)
  r->setID(d.id);
  r->setOpcode(0);

  // reserve some space
  r->stringbuffer.reserve(d_qlen+12);
  // copy the question in
  r->setQ(r->stringbuffer.c_str()+12,d_qlen);
  r->d.qdcount=1;
  
  r->d_dt=d_dt;

  return r;
}

I accidentally forgot the r-> before stringbuffer.reserve(d_qlen+12), which
caused a request to reserve a smaller space then currently used by
stringbuffer. The method was not const, which caused gcc not to notice the
error.

Backtrace of the coredump, somewhat incorrect:

#0  0x08075887 in std::__default_alloc_template<true, 0>::allocate(unsigned)
()
    at eval.c:41
#1  0x080747d6 in std::string::_Rep::_S_create(unsigned,
std::allocator<char>
+const&) () at eval.c:41
#2  0x08073535 in std::string::_Rep::_M_clone(std::allocator<char> const&,
+unsigned) () at eval.c:41
#3  0x080737d5 in std::string::reserve(unsigned) () at eval.c:41
#4  0x0805cf17 in DNSPacket::replyPacket() () at eval.c:41
#5  0x0806aee7 in PacketHandler::question(DNSPacket*) () at eval.c:41
#6  0x080739e0 in Distributor<DNSPacket, DNSPacket,
+PacketHandler>::makeThread(void*) () at eval.c:41
#7  0x40020efa in pthread_detach () from /lib/libpthread.so.0

I think the problem is due to this line in basic_string.tcc:

      if (__res > this->capacity() || _M_rep()->_M_is_shared())

and then this one:

          _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());

This probably leads to a negative clone() request.

>How-To-Repeat:
        
>Fix:
        


Reply via email to