Thread: overlapping strncpy/memcpy errors via valgrind

overlapping strncpy/memcpy errors via valgrind

From
Andres Freund
Date:
==24373== Source and destination overlap in strncpy(0x28b892f5, 0x28b892f5, 64)
==24373==    at 0x402A8F2: strncpy (mc_replace_strmem.c:477)
==24373==    by 0x7D563F: namestrcpy (name.c:221)
==24373==    by 0x46DF31: TupleDescInitEntry (tupdesc.c:473)
==24373==    by 0x889EC3: resolve_polymorphic_tupdesc (funcapi.c:573)
==24373==    by 0x889873: internal_get_result_type (funcapi.c:322)
==24373==    by 0x8896A2: get_expr_result_type (funcapi.c:235)
==24373==    by 0x594577: addRangeTableEntryForFunction (parse_relation.c:1206)
==24373==    by 0x57D81E: transformRangeFunction (parse_clause.c:550)
==24373==    by 0x57DBE1: transformFromClauseItem (parse_clause.c:658)
==24373==    by 0x57CF01: transformFromClause (parse_clause.c:120)
==24373==    by 0x54F9A5: transformSelectStmt (analyze.c:925)
==24373==    by 0x54E4E9: transformStmt (analyze.c:242)

==24373== Source and destination overlap in memcpy(0x546abc0, 0x546abc0, 24)
==24373==    at 0x402B930: memcpy (mc_replace_strmem.c:883)
==24373==    by 0x853BAB: uniqueentry (tsvector.c:127)
==24373==    by 0x8541A5: tsvectorin (tsvector.c:262)
==24373==    by 0x888781: InputFunctionCall (fmgr.c:1916)
==24373==    by 0x888A7D: OidInputFunctionCall (fmgr.c:2047)
==24373==    by 0x59B6D7: stringTypeDatum (parse_type.c:592)
==24373==    by 0x580E14: coerce_type (parse_coerce.c:303)
==24373==    by 0x580AD4: coerce_to_target_type (parse_coerce.c:101)
==24373==    by 0x58B802: transformTypeCast (parse_expr.c:2222)
==24373==    by 0x587484: transformExprRecurse (parse_expr.c:208)
==24373==    by 0x587156: transformExpr (parse_expr.c:116)
==24373==    by 0x5975CC: transformTargetEntry (parse_target.c:94)

I didn't check out the tsvector case but the
resolve_polymorphic_tupdesc/TupleDescInitEntry is clearly bogusly coded.

Do we care? strncpy'ing a string over itself isn't defined...

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: overlapping strncpy/memcpy errors via valgrind

From
Greg Stark
Date:
<p dir="ltr">Peter G is sitting near me and reminded me that this issue came up in the past. Iirc the conclusion then
isthat we're calling memcpy where the source and destination pointers are sometimes identical. Tom decided there was
reallyno realistic architecture where that wouldn't work. We're not calling it on overlapping nonidentical pointers.
<divclass="gmail_quote">On Feb 17, 2013 2:22 PM, "Andres Freund" <<a
href="mailto:andres@2ndquadrant.com">andres@2ndquadrant.com</a>>wrote:<br type="attribution" /><blockquote
class="gmail_quote"style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> ==24373== Source and
destinationoverlap in strncpy(0x28b892f5, 0x28b892f5, 64)<br /> ==24373==    at 0x402A8F2: strncpy
(mc_replace_strmem.c:477)<br/> ==24373==    by 0x7D563F: namestrcpy (name.c:221)<br /> ==24373==    by 0x46DF31:
TupleDescInitEntry(tupdesc.c:473)<br /> ==24373==    by 0x889EC3: resolve_polymorphic_tupdesc (funcapi.c:573)<br />
==24373==   by 0x889873: internal_get_result_type (funcapi.c:322)<br /> ==24373==    by 0x8896A2: get_expr_result_type
(funcapi.c:235)<br/> ==24373==    by 0x594577: addRangeTableEntryForFunction (parse_relation.c:1206)<br /> ==24373==  
 by0x57D81E: transformRangeFunction (parse_clause.c:550)<br /> ==24373==    by 0x57DBE1: transformFromClauseItem
(parse_clause.c:658)<br/> ==24373==    by 0x57CF01: transformFromClause (parse_clause.c:120)<br /> ==24373==    by
0x54F9A5:transformSelectStmt (analyze.c:925)<br /> ==24373==    by 0x54E4E9: transformStmt (analyze.c:242)<br /><br />
==24373==Source and destination overlap in memcpy(0x546abc0, 0x546abc0, 24)<br /> ==24373==    at 0x402B930: memcpy
(mc_replace_strmem.c:883)<br/> ==24373==    by 0x853BAB: uniqueentry (tsvector.c:127)<br /> ==24373==    by 0x8541A5:
tsvectorin(tsvector.c:262)<br /> ==24373==    by 0x888781: InputFunctionCall (fmgr.c:1916)<br /> ==24373==    by
0x888A7D:OidInputFunctionCall (fmgr.c:2047)<br /> ==24373==    by 0x59B6D7: stringTypeDatum (parse_type.c:592)<br />
==24373==   by 0x580E14: coerce_type (parse_coerce.c:303)<br /> ==24373==    by 0x580AD4: coerce_to_target_type
(parse_coerce.c:101)<br/> ==24373==    by 0x58B802: transformTypeCast (parse_expr.c:2222)<br /> ==24373==    by
0x587484:transformExprRecurse (parse_expr.c:208)<br /> ==24373==    by 0x587156: transformExpr (parse_expr.c:116)<br />
==24373==   by 0x5975CC: transformTargetEntry (parse_target.c:94)<br /><br /> I didn't check out the tsvector case but
the<br/> resolve_polymorphic_tupdesc/TupleDescInitEntry is clearly bogusly coded.<br /><br /> Do we care? strncpy'ing a
stringover itself isn't defined...<br /><br /> Greetings,<br /><br /> Andres Freund<br /><br /> --<br />  Andres Freund
                   <a href="http://www.2ndQuadrant.com/" target="_blank">http://www.2ndQuadrant.com/</a><br />
 PostgreSQLDevelopment, 24x7 Support, Training & Services<br /><br /><br /> --<br /> Sent via pgsql-hackers mailing
list(<a href="mailto:pgsql-hackers@postgresql.org">pgsql-hackers@postgresql.org</a>)<br /> To make changes to your
subscription:<br/><a href="http://www.postgresql.org/mailpref/pgsql-hackers"
target="_blank">http://www.postgresql.org/mailpref/pgsql-hackers</a><br/></blockquote></div> 

Re: overlapping strncpy/memcpy errors via valgrind

From
Andres Freund
Date:
On 2013-02-17 15:10:35 +0000, Greg Stark wrote:
> Peter G is sitting near me and reminded me that this issue came up in the
> past. Iirc the conclusion then is that we're calling memcpy where the
> source and destination pointers are sometimes identical. Tom decided there
> was really no realistic architecture where that wouldn't work. 

I am not so convinced that that is safe if libc turns that into some
optimized string instructions or even PCMPSTR...

> We're not calling it on overlapping nonidentical pointers.

Yup, the backtrace shows that...

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



Re: overlapping strncpy/memcpy errors via valgrind

From
Tom Lane
Date:
Andres Freund <andres@2ndquadrant.com> writes:
> On 2013-02-17 15:10:35 +0000, Greg Stark wrote:
>> Peter G is sitting near me and reminded me that this issue came up in the
>> past. Iirc the conclusion then is that we're calling memcpy where the
>> source and destination pointers are sometimes identical. Tom decided there
>> was really no realistic architecture where that wouldn't work. 

> I am not so convinced that that is safe if libc turns that into some
> optimized string instructions or even PCMPSTR...

What would you envision happening that would be bad?  The reason
overlapping source/dest is undefined is essentially that the function is
allowed to copy bytes in an unspecified order.  But if the pointers are
the same, then no matter what it does, no individual store will replace
a byte with a different value than it had, and so it's not possible for
the order of operations to matter.

I don't think it's worth contorting the source code to suppress this
complaint.  In the case of resolve_polymorphic_tupdesc, for instance,
dodging this warning would require that we not use TupleDescInitEntry to
update the data type of an attribute, but instead have this code know
all about the subsidiary fields that get set from the datatype.  I'm not
seeing that as an improvement ...
        regards, tom lane



Re: overlapping strncpy/memcpy errors via valgrind

From
Boszormenyi Zoltan
Date:
2013-02-17 16:32 keltezéssel, Tom Lane írta:
> Andres Freund <andres@2ndquadrant.com> writes:
>> On 2013-02-17 15:10:35 +0000, Greg Stark wrote:
>>> Peter G is sitting near me and reminded me that this issue came up in the
>>> past. Iirc the conclusion then is that we're calling memcpy where the
>>> source and destination pointers are sometimes identical. Tom decided there
>>> was really no realistic architecture where that wouldn't work.
>> I am not so convinced that that is safe if libc turns that into some
>> optimized string instructions or even PCMPSTR...
> What would you envision happening that would be bad?  The reason
> overlapping source/dest is undefined is essentially that the function is
> allowed to copy bytes in an unspecified order.  But if the pointers are
> the same, then no matter what it does, no individual store will replace
> a byte with a different value than it had, and so it's not possible for
> the order of operations to matter.

Then, why isn't memcpy() skipped if the source and dest are the same?
It would be a micro-optimization but a valid one.

> I don't think it's worth contorting the source code to suppress this
> complaint.  In the case of resolve_polymorphic_tupdesc, for instance,
> dodging this warning would require that we not use TupleDescInitEntry to
> update the data type of an attribute, but instead have this code know
> all about the subsidiary fields that get set from the datatype.  I'm not
> seeing that as an improvement ...
>
>             regards, tom lane
>
>


--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de     http://www.postgresql.at/




Re: overlapping strncpy/memcpy errors via valgrind

From
Tom Lane
Date:
Boszormenyi Zoltan <zb@cybertec.at> writes:
> Then, why isn't memcpy() skipped if the source and dest are the same?
> It would be a micro-optimization but a valid one.

No, it'd be more like a micro-pessimization, because the test would be
wasted effort in the vast majority of calls.  The *only* reason to do
this would be to shut up valgrind, and that seems annoying.

I wonder if anyone's tried filing a bug against valgrind to say that it
shouldn't complain about this case.
        regards, tom lane



Re: overlapping strncpy/memcpy errors via valgrind

From
Greg Stark
Date:
On Sun, Feb 17, 2013 at 4:26 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> No, it'd be more like a micro-pessimization, because the test would be
> wasted effort in the vast majority of calls.  The *only* reason to do
> this would be to shut up valgrind, and that seems annoying.

In terms of runtime I strongly suspect the effect would be 0 due to
branch prediction.

The effect on the code cleanliness seems like a stronger argument but
I have a hard time getting upset about a single one-line if statement
in namestrcpy. I suspect the argument may have been that we have no
reason to believe namestrcpy is the only place this can happen.

-- 
greg



Re: overlapping strncpy/memcpy errors via valgrind

From
"anarazel@anarazel.de"
Date:

Tom Lane <tgl@sss.pgh.pa.us> schrieb:

>Andres Freund <andres@2ndquadrant.com> writes:
>> On 2013-02-17 15:10:35 +0000, Greg Stark wrote:
>>> Peter G is sitting near me and reminded me that this issue came up
>in the
>>> past. Iirc the conclusion then is that we're calling memcpy where
>the
>>> source and destination pointers are sometimes identical. Tom decided
>there
>>> was really no realistic architecture where that wouldn't work.
>
>> I am not so convinced that that is safe if libc turns that into some
>> optimized string instructions or even PCMPSTR...
>
>What would you envision happening that would be bad?

Afair some of the optimized instructions (like movdqa) don't necessarily work if source an target are in the same
location.Not sure about it bit I wouldn't want to depend on it. 

Andres


---
Please excuse brevity and formatting - I am writing this on my mobile phone.



Re: overlapping strncpy/memcpy errors via valgrind

From
"anarazel@anarazel.de"
Date:

Tom Lane <tgl@sss.pgh.pa.us> schrieb:

>Boszormenyi Zoltan <zb@cybertec.at> writes:
>> Then, why isn't memcpy() skipped if the source and dest are the same?
>> It would be a micro-optimization but a valid one.
>
>No, it'd be more like a micro-pessimization, because the test would be
>wasted effort in the vast majority of calls.  The *only* reason to do
>this would be to shut up valgrind, and that seems annoying.
>
>I wonder if anyone's tried filing a bug against valgrind to say that it
>shouldn't complain about this case.

You already need a suppression file to use valgrind sensibly, its easy enough to add it there. Perhaps we should add
oneto the tree? 

---
Please excuse brevity and formatting - I am writing this on my mobile phone.



Re: overlapping strncpy/memcpy errors via valgrind

From
Peter Geoghegan
Date:
On 17 February 2013 18:52, anarazel@anarazel.de <andres@anarazel.de> wrote:
> You already need a suppression file to use valgrind sensibly, its easy enough to add it there. Perhaps we should add
oneto the tree?
 

Perhaps you should take the time to submit a proper Valgrind patch
first. The current approach of applying the patch that Noah Misch
originally wrote (but did not publicly submit, iirc) on an ad-hoc
basis isn't great. That is what you've done here, right?


-- 
Regards,
Peter Geoghegan



Re: overlapping strncpy/memcpy errors via valgrind

From
"anarazel@anarazel.de"
Date:

Peter Geoghegan <peter.geoghegan86@gmail.com> schrieb:

>On 17 February 2013 18:52, anarazel@anarazel.de <andres@anarazel.de>
>wrote:
>> You already need a suppression file to use valgrind sensibly, its
>easy enough to add it there. Perhaps we should add one to the tree?
>
>Perhaps you should take the time to submit a proper Valgrind patch
>first. The current approach of applying the patch that Noah Misch
>originally wrote (but did not publicly submit, iirc) on an ad-hoc
>basis isn't great. That is what you've done here, right?

What patch are you talking about? I have no knowledge about any pending valgrind patches except one I made upstream
applyto make pg inside valgrind work on amd64. 

Andres

---
Please excuse brevity and formatting - I am writing this on my mobile phone.



Re: overlapping strncpy/memcpy errors via valgrind

From
Peter Geoghegan
Date:
On 17 February 2013 19:39, anarazel@anarazel.de <andres@anarazel.de> wrote:
> What patch are you talking about? I have no knowledge about any pending valgrind patches except one I made upstream
applyto make pg inside valgrind work on amd64.
 

Noah wrote a small patch, which he shared with me privately, which
added Valgrind hook macros to aset.c and mcxt.c. The resulting
Valgrind run threw up some things that were reported publicly [1]. I
documented much of his work on the wiki. I was under the impression
that this was the best way to get Valgrind to work with Postgres
(apparently there were problems with many false positives otherwise).

[1] http://www.postgresql.org/message-id/20110312133224.GA7833@tornado.gateway.2wire.net

-- 
Regards,
Peter Geoghegan



Re: overlapping strncpy/memcpy errors via valgrind

From
Andres Freund
Date:
On 2013-02-17 19:52:16 +0000, Peter Geoghegan wrote:
> On 17 February 2013 19:39, anarazel@anarazel.de <andres@anarazel.de> wrote:
> > What patch are you talking about? I have no knowledge about any pending valgrind patches except one I made upstream
applyto make pg inside valgrind work on amd64.
 
> 
> Noah wrote a small patch, which he shared with me privately, which
> added Valgrind hook macros to aset.c and mcxt.c. The resulting
> Valgrind run threw up some things that were reported publicly [1]. I
> documented much of his work on the wiki. I was under the impression
> that this was the best way to get Valgrind to work with Postgres
> (apparently there were problems with many false positives otherwise).
> 
> [1] http://www.postgresql.org/message-id/20110312133224.GA7833@tornado.gateway.2wire.net

Nice, I wasn't aware of that work. I always wanted to add that
instrumentation but never got arround to it.
PG runs without problems for me with the exception of some warnings that
I suppress.
Would be nice to get that upstream...

> For reasons that have yet to be ascertained, it is necessary to run the
>  regression tests with autovacuum = 'off'. Otherwise, Postgres will segfault
>  within an autovacuum worker's elog() call.

That's the bug I was referring to, its fixed at least in svn. It failed
in far more places than that, basically everywhere an instruction that
required the stack to be properly aligned was executed.
The problem was that valgrind didn't align the new stack properly after
a fork if the fork was executed inside a signal handler. Which pg
happens to do...

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services