bug-commoncpp
[Top][All Lists]
Advanced

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

Segmentation fault//memcpy misuse with command options (partial fix patc


From: Joshua Moore-Oliva
Subject: Segmentation fault//memcpy misuse with command options (partial fix patch included)
Date: Fri, 9 Apr 2004 04:02:34 -0400
User-agent: KMail/1.6.1

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)




reply via email to

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