bug-commoncpp
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Segmentation fault//memcpy misuse with command options (partial fix


From: David Sugar
Subject: Re: Segmentation fault//memcpy misuse with command options (partial fix patch included)
Date: Sat, 10 Apr 2004 05:58:32 -0400
User-agent: KMail/1.6.2

My first thought is that most of these operations depend on getLength 
returning the correct string length (in effect strlen() + 1 null byte).  
However, the String class actually stores a length field, which is what 
getLength() actually returns, and maybe that length field is not being kept 
in sync with the actual string length in some circumstances!  It would be 
interesting to compare the length returned by getLength with the length 
returned by strlen() in front of each of these memmove's...

On Friday 09 April 2004 05:00 pm, you wrote:
> In addition, none of these problems occur with commoncpp2 1.0.13 only in
> 1.1.2.
>
> Joshua Moore-Oliva.
>
> On April 8, 2004 9:19 pm, David Sugar wrote:
> > So what you did is basically replace every memcpy with a memmove? 
> > Hmm...in at least some cases, memcpy may be inline'd with assembler code.
> >  Perhaps there is something odd in the inline code substitution?  Also,
> > your patch got a little chopped up in the debugging text...
> >
> > David
> >
> > On Friday 09 April 2004 04:02 am, Joshua Moore-Oliva wrote:
> > > I created a program with quite a few options, and I got a segmentation
> > > fault that appears to be a mis-use of memcpy.
> > >
> > > Included is a test program to reproduce the problem and some debugging
> > > output.
> > >
> > > I was able to remove the problems with memcpy with the changes in the
> > > included patch, however I am not familiar enough with the code to
> > > determine why the getSpace function in the String library is going out
> > > of bounds...
> > >
> > > debugging output before patch
> > >
> > > ==17692== Source and destination overlap in memcpy(0x41E1A83C,
> > > 0x41E1A87C, 86) ==17692==    at 0x40022224: memcpy (in
> > > /usr/lib/valgrind/vgskin_memcheck.so) ==17692==    by 0x40277A94:
> > > ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B7B10:
> > > ost::CommandOptionParse_impl::makePrintErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6CAC:
> > > ost::CommandOptionParse_impl::printErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BD8: main (in
> > > /home/chatgris/a.out)
> > > ==17692==
> > > ==17692== Source and destination overlap in memcpy(0x41E1A87C,
> > > 0x41E1A83C, 87) ==17692==    at 0x40022224: memcpy (in
> > > /usr/lib/valgrind/vgskin_memcheck.so) ==17692==    by 0x40277C75:
> > > ost::String::copy(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x4027647B:
> > > ost::String::String(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x4027887C:
> > > ost::operator+(ost::String const&, char const*) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B7B83:
> > > ost::CommandOptionParse_impl::makePrintErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6CAC:
> > > ost::CommandOptionParse_impl::printErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BD8: main (in
> > > /home/chatgris/a.out)
> > > ==17692==
> > > ==17692== Source and destination overlap in memcpy(0x41E1AC68,
> > > 0x41E1ABA8, 215) ==17692==    at 0x40022224: memcpy (in
> > > /usr/lib/valgrind/vgskin_memcheck.so) ==17692==    by 0x40278310:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==17692==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B7DD5:
> > > ost::CommandOptionParse_impl::makePrintErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6CAC:
> > > ost::CommandOptionParse_impl::printErrors() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BD8: main (in
> > > /home/chatgris/a.out)
> > > Value required for option '--connection_string' is missing
> > > Value==17692==
> > > ==17692== Source and destination overlap in memcpy(0x41E1A7BC,
> > > 0x41E1A7DC, 41) ==17692==    at 0x40022224: memcpy (in
> > > /usr/lib/valgrind/vgskin_memcheck.so) ==17692==    by 0x40277C75:
> > > ost::String::copy(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x4027647B:
> > > ost::String::String(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402787B2:
> > > ost::operator+(ost::String const&, char) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B8015:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BFA: main (in
> > > /home/chatgris/a.out)
> > > ==17692==
> > > ==17692== Invalid read of size 4
> > > ==17692==    at 0x40278576: ost::String::getSpace(unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==17692==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B16C1:
> > > oValue==26722== Invalid read of size 4 ==26722==    at 0x40278576:
> > > ost::String::getSpace(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)
> > > ==26722==  Address 0x20202020 is not stack'd, malloc'd or free'd
> > > ==26722==
> > > ==26722== Process terminating with default action of signal 11
> > > (SIGSEGV): dumping core ==26722==  Address not mapped to object at
> > > address 0x20202020 ==26722==    at 0x40278576:
> > > ost::String::getSpace(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)st::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BFA: main (in
> > > /home/chatgris/a.out)
> > > ==17692==  Address 0x20202020 is not stack'd, malloc'd or free'd
> > > ==17692==
> > > ==17692== Process terminating with default action of signal 11
> > > (SIGSEGV): dumping core ==17692==  Address not mapped to object at
> > > address 0x20202020 ==17692==    at 0x40278576:
> > > ost::String::getSpace(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==17692==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==17692==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==17692==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==17692==    by 0x8048BFA: main (in
> > > /home/chatgris/a.out)
> > >
> > >
> > > test case
> > >
> > > #include <iostream>
> > > #include <cc++/common.h>
> > >
> > > ost::CommandOptionArg optConnInfo (
> > >   "connection_string", "c", "Connection String.", true
> > > );
> > >
> > > ost::CommandOptionArg optMergeDelimiterField (
> > >   "field_delimiter", "f", "Field delimiter for merge information", true
> > > );
> > >
> > > ost::CommandOptionArg optMergeDelimiterRecord (
> > >   "record_delimiter", "r", "Record delimiter for merge information",
> > > true );
> > >
> > > ost::CommandOptionArg optMergeNames (
> > >   "merge_names", "n", "Merge Field Names (tab delimited)", true
> > > );
> > >
> > > ost::CommandOptionArg optMessageSource (
> > >   "message_source", "s", "Message Source", true
> > > );
> > >
> > > ost::CommandOptionArg optQuery (
> > >   "query", "q", "Query to retrieve send data", true
> > > );
> > >
> > > ost::CommandOptionArg optSortDir (
> > >   "sort_dir", "sd", "Directory where the sort binary resides", true
> > > );
> > >
> > > ost::CommandOptionArg optSortName (
> > >   "sort_name", "sn", "Name of the sort binary", true
> > > );
> > >
> > > ost::CommandOptionArg optSortTmpDir (
> > >   "sort_tmp_dir", "st", "Temp dir for sort to use", true
> > > );
> > >
> > > ost::CommandOptionArg optMaxBatchSize (
> > >   "max_batch_size", "b", "Maximum Batch Size", true
> > > );
> > >
> > > ost::CommandOptionArg optPriority (
> > >   "priority", "p", "Priority for mailing", true
> > > );
> > >
> > > ost::CommandOptionNoArg optHelpArg (
> > >   "help", "?", "Print help usage"
> > > );
> > >
> > > int main ( int argc, char ** argv ) {
> > >   ost::CommandOptionParse * optArgs =
> > >     ost::makeCommandOptionParse ( argc
> > >                                 , argv
> > >                                 , "Configurable Procmail receiver.\n"
> > >   );
> > >
> > >   // If the user requested help then suppress all the usage error
> > >   // messages.
> > >   if ( optHelpArg.numSet ) {
> > >     std::cerr << optArgs->printUsage();
> > >     return 0;
> > >   }
> > >
> > >   // Print usage your way.
> > >   if ( optArgs->argsHaveError() ) {
> > >     std::cerr << optArgs->printErrors();
> > >     std::cerr << optArgs->printUsage();
> > >     return 1;
> > >   }
> > >
> > >   std::cout << "Success" << std::endl;
> > >
> > >   delete optArgs;
> > >
> > >   return 0;
> > > }
> > >
> > > Patch to get rid of memcpy
> > >
> > > 170c170
> > > <               memmove(ptr + start, str, count);
> > > ---
> > >
> > > >               memcpy(ptr + start, str, count);
> > >
> > > 218c218
> > > <       memmove(ptr + start, ptr + start + count, len - start - count);
> > > ---
> > >
> > > >       memcpy(ptr + start, ptr + start + count, len - start - count);
> > >
> > > 253c253
> > > <       memmove(getText() + getLength(), str, len);
> > > ---
> > >
> > > >       memcpy(getText() + getLength(), str, len);
> > >
> > > 391c391
> > > <       memmove(getText(), str, Value==26722== Invalid read of size 4
> > > ==26722==    at 0x40278576: ost::String::getSpace(unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)
> > > ==26722==  Address 0x20202020 is not stack'd, malloc'd or free'd
> > > ==26722==
> > > ==26722== Process terminating with default action of signal 11
> > > (SIGSEGV): dumping core ==26722==  Address not mapped to object at
> > > address 0x20202020 ==26722==    at 0x40278576:
> > > ost::String::getSpace(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)len);
> > > ---
> > >
> > > >       memcpy(getText(), str, len);
> > >
> > > 418c418
> > > <               memmove(content.ministring.text, getText(), getLength()
> > > + 1); ---
> > >
> > > >               memcpy(content.ministring.text, getText(), getLength()
> > > > + 1);
> > >
> > > 426c426
> > > <       memmove(content.bigstring.text, ptr, getLength() + 1);
> > > ---
> > >
> > > >       memcpy(content.bigstring.text, ptr, getLength() + 1);
> > >
> > > 576c576
> > > <               memmove(ptr, content.ministring.text, length);
> > > ---
> > >
> > > >               memcpy(ptr, content.ministring.text, length);
> > >
> > > 588c588
> > > <               memmove(content.ministring.text, ptr, length);
> > > ---
> > >
> > > >               memcpy(content.ministring.text, ptr, length);
> > >
> > > 597c597
> > > <       memmove(ptr, getText(), length);
> > > ---
> > >
> > > >       memcpy(ptr, getText(), length);
> > >
> > > Debugging results of above program after patch applied
> > >
> > > Value==26722== Invalid read of size 4
> > > ==26722==    at 0x40278576: ost::String::getSpace(unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)
> > > ==26722==  Address 0x20202020 is not stack'd, malloc'd or free'd
> > > ==26722==
> > > ==26722== Process terminating with default action of signal 11
> > > (SIGSEGV): dumping core ==26722==  Address not mapped to object at
> > > address 0x20202020 ==26722==    at 0x40278576:
> > > ost::String::getSpace(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x402781F6:
> > > ost::String::resize(unsigned) (in /usr/lib/libccgnu2-1.1.so.0.0.2)
> > > ==26722==    by 0x40277A71: ost::String::set(char const*, unsigned) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x40277B07:
> > > ost::String::set(ost::String const&) (in
> > > /usr/lib/libccgnu2-1.1.so.0.0.2) ==26722==    by 0x402B16C1:
> > > ost::String::operator=(ost::String const&) (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B802A:
> > > ost::CommandOptionParse_impl::makePrintUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x402B6C7A:
> > > ost::CommandOptionParse_impl::printUsage() (in
> > > /usr/lib/libccext2-1.1.so.0.0.2) ==26722==    by 0x8048BFA: main
> > > (main.cpp:69)
> > >
> > >
> > > _______________________________________________
> > > Bug-commoncpp mailing list
> > > address@hidden
> > > http://mail.gnu.org/mailman/listinfo/bug-commoncpp




reply via email to

[Prev in Thread] Current Thread [Next in Thread]