Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > strcpy overlapping memory

Reply
Thread Tools

strcpy overlapping memory

 
 
Michael Foukarakis
Guest
Posts: n/a
 
      12-06-2010
On Dec 3, 6:04*pm, JohnF <(E-Mail Removed)> wrote:
> Any problem with code of the form
> * unsigned char s[999] = "0123456789";
> * strcpy(s+2,s+4);
> which, in this case, would result in "01456789" ?
>
> Someone reported a problem with one of my programs
> that he resolved by replacing this kind of strcpy
> with an equivalent memmove after valgrind reported
> the overlapping memory. But when I asked him what
> input he used, so I could reproduce the problem,
> he couldn't remember, and then he couldn't reproduce
> the problem himself.


If your strcpy() copies backwards, you will most certainly corrupt
your buffer. A recent glibc change exposed several such bugs on
software like flash player on Linux, see [1].

[1] https://bugzilla.redhat.com/show_bug.cgi?id=638477
 
Reply With Quote
 
 
 
 
JohnF
Guest
Posts: n/a
 
      12-06-2010
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> JohnF <(E-Mail Removed)> wrote:
>> But the above example's giving me a little problem. For strcpy
>> to "work under some circumstances", the compiler has to add
>> extra instructions to check the input strings and choose how to
>> proceed accordingly.

>
> Consider a machine with a move characters instruction with a maximum
> length of 256 characters. A strcpy implementation might well use that
> instruction, but have to add a loop around it in case the string is
> longer than that. If the instruction handles overlapping moves
> correctly but the loop always works the same way, then short strings
> always work right, but longer strings may or may not work depending on
> the direction and offset of the overlap.


Thanks again Larry, Eric, Seebs, JJ, etc.
And, like you guys said, I >>am<< surprised such runtime optimizations
work, i.e., that, on average, they save more time than they cost.
It also somewhat tarnishes my picture of C the way it's often
described as a "portable assembly language". In that picture, I'd
kind of hope that strcpy would just assemble to some straightforward
move instruction, along with whatever '\000' end-of-string check
is available in the particular instruction set. If they want
to add optimizations, they could at least reserve them for -O3,
or something like that.
And one other thing continues to surprise me: if they're adding
all this code to check args, I'd of thought they'd at least check
for NULL's. I've had more than a few programs segfault due to a
blunder during development passing strcpy a NULL arg. With all this
strcpy arg checking going on, couldn't they check for NULL?
--
John Forkosh ( mailto: (E-Mail Removed) where j=john and f=forkosh )
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      12-06-2010
JohnF <(E-Mail Removed)> writes:
[...]
> And one other thing continues to surprise me: if they're adding
> all this code to check args, I'd of thought they'd at least check
> for NULL's. I've had more than a few programs segfault due to a
> blunder during development passing strcpy a NULL arg. With all this
> strcpy arg checking going on, couldn't they check for NULL?


Check for NULL and do what?

If strcpy(s, NULL) quietly does nothing, the implementation isn't
doing you any favors. A seg fault or equivalent is the best thing
it can do to help you track down the error in your program.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      12-07-2010


"Keith Thompson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> JohnF <(E-Mail Removed)> writes:
> [...]
>> And one other thing continues to surprise me: if they're adding
>> all this code to check args, I'd of thought they'd at least check
>> for NULL's. I've had more than a few programs segfault due to a
>> blunder during development passing strcpy a NULL arg. With all this
>> strcpy arg checking going on, couldn't they check for NULL?

>
> Check for NULL and do what?


Pretend it's ""?

> If strcpy(s, NULL) quietly does nothing, the implementation isn't
> doing you any favors. A seg fault or equivalent is the best thing
> it can do to help you track down the error in your program.


(And what would the application then do?)

If these functions were well-behaved with NULL arguments, it would save the
caller having to do the checks, or to do the checks and replace them with
pointers to empty strings.

NULL is not necessarily an error; it would be handy to sometimes deal with
NULL as though it was an empty string.

--
Bartc

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-07-2010
"BartC" <(E-Mail Removed)> writes:
> "Keith Thompson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> JohnF <(E-Mail Removed)> writes:
>> [...]
>>> And one other thing continues to surprise me: if they're adding
>>> all this code to check args, I'd of thought they'd at least check
>>> for NULL's. I've had more than a few programs segfault due to a
>>> blunder during development passing strcpy a NULL arg. With all this
>>> strcpy arg checking going on, couldn't they check for NULL?

>>
>> Check for NULL and do what?

>
> Pretend it's ""?


Why?

>> If strcpy(s, NULL) quietly does nothing, the implementation isn't
>> doing you any favors. A seg fault or equivalent is the best thing
>> it can do to help you track down the error in your program.

>
> (And what would the application then do?)


Presumably it would crash -- and the developer would then fix the bug
so it doesn't crash next time.

> If these functions were well-behaved with NULL arguments, it would save the
> caller having to do the checks, or to do the checks and replace them with
> pointers to empty strings.
>
> NULL is not necessarily an error; it would be handy to sometimes deal with
> NULL as though it was an empty string.


Or a string of length SIZE_MAX, maybe?

Passing a null pointer to strcpy() *is* necessarily an error. strlen()
could have been defined to return the length of string pointed to by its
arguments, or 0 if the argument is a null pointer. But it wasn't
defined that way. If you want such a function, feel free to write it.

NULL isn't a pointer to an empty string. It's a pointer value that
doesn't point to anything, and that's a valuable distinction that
I shouldn't be ignored by the standard library.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
J. J. Farrell
Guest
Posts: n/a
 
      12-07-2010
Keith Thompson wrote:
> "BartC" <(E-Mail Removed)> writes:
>> "Keith Thompson" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>> JohnF <(E-Mail Removed)> writes:
>>> [...]
>>>> And one other thing continues to surprise me: if they're adding
>>>> all this code to check args, I'd of thought they'd at least check
>>>> for NULL's. I've had more than a few programs segfault due to a
>>>> blunder during development passing strcpy a NULL arg. With all this
>>>> strcpy arg checking going on, couldn't they check for NULL?
>>> Check for NULL and do what?

>> Pretend it's ""?

>
> Why?
>
>>> If strcpy(s, NULL) quietly does nothing, the implementation isn't
>>> doing you any favors. A seg fault or equivalent is the best thing
>>> it can do to help you track down the error in your program.

>> (And what would the application then do?)

>
> Presumably it would crash -- and the developer would then fix the bug
> so it doesn't crash next time.
>
>> If these functions were well-behaved with NULL arguments, it would save the
>> caller having to do the checks, or to do the checks and replace them with
>> pointers to empty strings.
>>
>> NULL is not necessarily an error; it would be handy to sometimes deal with
>> NULL as though it was an empty string.

>
> Or a string of length SIZE_MAX, maybe?
>
> Passing a null pointer to strcpy() *is* necessarily an error. strlen()
> could have been defined to return the length of string pointed to by its
> arguments, or 0 if the argument is a null pointer. But it wasn't
> defined that way. If you want such a function, feel free to write it.
>
> NULL isn't a pointer to an empty string. It's a pointer value that
> doesn't point to anything, and that's a valuable distinction that
> I shouldn't be ignored by the standard library.


Not arguing the merits one way or another, but it's a little surprising
that things ended up defined this way. Some relatively mature versions
of UNIX had the assumption effectively built in that, in string context,
a null pointer was equivalent to a pointer to an empty string. There
were thousands of places in the SVR3 source which depended on that. It
was implemented by having the null pointer point to zero and mapping a
page of zeroes at zero so that the string functions didn't have to
detect or special-case it.
 
Reply With Quote
 
James Dow Allen
Guest
Posts: n/a
 
      12-07-2010
JohnF <(E-Mail Removed)> might have writ, in
news:idjbj9$j4j$(E-Mail Removed):

> It also somewhat tarnishes my picture of C the way it's often
> described as a "portable assembly language". In that picture, I'd
> kind of hope that strcpy would just assemble to some straightforward
> move instruction, along with whatever '\000' end-of-string check
> is available in the particular instruction set. If they want
> to add optimizations, they could at least reserve them for -O3,
> or something like that.


As someone who also views C as a "portable assembly language" and loves
it for that reason, let me defend C here! A key meaning in that phrase
is C's *determinism* and if the end-result of strcpy() (when used
according to its rules!) is completely defined, what's to complain
about? (Anyway, strcpy() is part of a standard library, not the
language itself, though to say more on that would encourage a round of
semantic quibbling, as well as the objection that complications can
arise even in "parts of the language.")

And anyway, even machine languages can do elaborate checking and get
peculiar results. Speaking of overlapped copy, the IBM 370 has to check
for overlap in the copy instruction MVC DEST(,SRC and, due to a
special wierdness on one model, it is possible to corrupt data with this
instruction *anyway*!

It isn't clear whether you were unaware of strcpy()'s overlap caveat or
were but chose to ignore it (?!). I also do overlapped copies from time
to time, but just roll my own olap_strcpy() for them. This is trivial
(the one-liner for strcpy() is famous!) and 99+% of the time squeezing
maximum efficiency is unnecessary.

> And one other thing continues to surprise me: if they're adding
> all this code to check args, I'd of thought they'd at least check
> for NULL's.


If your debuggable code accidentally passes NULL, Segfault is *exactly
what you want* (in the absence of any other checking) to get a core-dump
at the earliest point.

(BTW, NULL == "" on some early Dig Equip C systems. This seemed not
necessarily bad, but obviously didn't "catch on"!

James Dow Allen
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-07-2010
On 12/6/2010 7:46 PM, BartC wrote:
>
> "Keith Thompson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> [...]
>> If strcpy(s, NULL) quietly does nothing, the implementation isn't
>> doing you any favors. A seg fault or equivalent is the best thing
>> it can do to help you track down the error in your program.

>
> (And what would the application then do?)
>
> If these functions were well-behaved with NULL arguments, it would save the
> caller having to do the checks, or to do the checks and replace them with
> pointers to empty strings.
>
> NULL is not necessarily an error; it would be handy to sometimes deal with
> NULL as though it was an empty string.


Yes. Unfortunately, strcpy() and strcmp() and so on are unable
to distinguish venial from mortal sins. Think about it: Put yourself
in the place of the strcpy() implementation, and imagine you've been
told "Copy *this* to *that*." You salute and start trying to carry
out your orders, and you find that *this* doesn't exist. How can you
know whether substituting "" for *this* is a suitable response, or
whether you should fire three warning shots into the air and sound
the klaxon? Answer: You can't know. You're a lowly private, not in
the confidence of the strategic thinkers at HQ, and it is *not* your
place to "follow" your orders by fudging the results.

Or, shifting the analogy a bit:

"Puhkins."

"Yes, Mister Bank Manager, sahh?"

"Do be a good lad and make sure someone's guarding the gold
vault, won't you?"

"Veddy good, sahh. Right away, sahh." (Hmmm: Nobody's there,
the door is flapping in the breeze, and there's no sign of gold in
the empty interior.) "Nothing to worry about, sahh; NULL is on
guard."

"Splendid, Puhkins. Knew we could count on you. Here's half
a ha'penny for your good wife, and I do hope and trust she's put an
end to her sordid affair with that bounder NULL."

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      12-07-2010
On 12/07/2010 03:41 AM, Eric Sosman wrote:

> "Puhkins."
>
> "Yes, Mister Bank Manager, sahh?"
>
> "Do be a good lad and make sure someone's guarding the gold
> vault, won't you?"
>
> "Veddy good, sahh. Right away, sahh." (Hmmm: Nobody's there,
> the door is flapping in the breeze, and there's no sign of gold in
> the empty interior.) "Nothing to worry about, sahh; NULL is on
> guard."
>
> "Splendid, Puhkins. Knew we could count on you. Here's half
> a ha'penny for your good wife, and I do hope and trust she's put an
> end to her sordid affair with that bounder NULL."


I think they need to adjust your medication....
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      12-07-2010
> On Mon, 06 Dec 2010 11:26:01 -0800, Keith Thompson wrote:


> Check for NULL and do what?
>
> If strcpy(s, NULL) quietly does nothing, the implementation isn't doing
> you any favors. A seg fault or equivalent is the best thing it can do
> to help you track down the error in your program.


In my case, strcpy(s, NULL) Segfaults. I have done this mistake of not
checking arguments for NULL before passing them to strcpy(). Is there
anything wrong in checking for NULL before using Std Lib's string
functions ?




--
www.lispmachine.wordpress.com
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
strcpy and the copy constructor RonHiler C++ 8 10-19-2004 06:30 AM
C++ Compiler with a -Wwarn-use-of-strcpy or similar option?? Paul Sheer C++ 4 09-14-2004 08:38 PM
C++ Compiler with a -Wwarn-use-of-strcpy or similar option?? Paul Sheer C++ 7 09-10-2004 05:07 PM
strcpy Mike Mimic C++ 9 05-17-2004 08:12 PM
Declarations of structs, and arrays seem to be overlapping in memory..?! David Thorp C Programming 4 09-01-2003 11:46 PM



Advertisments