[squid-dev] [PATCH] xstrndup has to go
Amos Jeffries
squid3 at treenet.co.nz
Mon May 1 05:26:14 UTC 2017
On 30/04/17 04:17, Alex Rousskov wrote:
> On 04/29/2017 02:33 AM, Amos Jeffries wrote:
>
>> If that is too hard, making callers do the allocate bit themselves and
>> xstrncpy() instead should be a good medium-term workaround.
> In general, it is impossible to correctly replace strndup() with a
> simple allocate and strncpy() pair. I bet this impossibility is why
> strndup() exists! strndup() is not a convenience function, but an
> irreplaceable tool in a performance toolbox.
>
> Why is it impossible in general? Because you do not know how many bytes
> to allocate (that number may be much smaller than n) and you cannot use
> strlen() to find out because the array may not be 0-terminated. You need
> strnlen(), which is usually not available where strndup() is not.
We don't need to solve the general case. We need to solve the handful of
actual uses in Squid code, then add the risky function to the forbidden
list which is enforced by sourcemaintenance.sh.
>
>>> P.S. The OutOfBoundsException use case code fixed by this patch needs a
>>> different fix (the one that does not allocate memory twice):
>>>
>>> xstrndup(explanatoryText.rawContent(), explanatoryText.length());
>>>
>>> but we cannot do the above until xstrndup() implementation is fixed.
>> Not even by moving that caller to xmalloc() for itself and use xstrncpy() ?
> xmalloc()+xstrncpy() is not "doing the above" it is doing something
> else. I only claimed that we "cannot do the above" (literally). There
> are other ways to achieve the same result, of course. None of those
> other ways that I can think of (in the current code context) are better
> than the proposed double-copy IMO.
>
> Sure, it is possible to do xmalloc()+memcpy() in this context instead of
> xstrndup(), but, in this context, that would be arguably worse than
> copying twice because it would replace a clear high-level code with
> risky low-level manipulations on an error handling path.
>
> If strdup(buf.c_str()) pattern appears often, we should add
> SBuf::c_str_dup() that does xmalloc()+memcpy().
strdup != strndup.
For strdup() replacement we absolutely can do strlen(). It requires
nul-termination explicitly.
The xstrndup(F.c_str(), ...) pattern appears exactly once. In this
exception handler under discussion.
My question was about that one use-case you highlighted as example, not
the general solution. It appears to me that while there is some
variation caused by the message contents being filename and line numbers
- they are still short enough that over-allocation is not a huge problem
and whatever exception handler catches this will end with deallocation
quite quickly.
The relevant lines being these:
src/sbuf/Exceptions.cc: SBuf explanatoryText("OutOfBoundsException");
src/sbuf/Exceptions.cc: explanatoryText.appendf(" at line %d",
aLineNo);
src/sbuf/Exceptions.cc: explanatoryText.appendf(" in file %s",
aFileName);
src/sbuf/Exceptions.cc: explanatoryText.appendf(" while accessing
position %d in a SBuf long %d",
src/sbuf/Exceptions.cc: message =
xstrndup(explanatoryText.c_str(),explanatoryText.length());
Over-allocation appears to only be possible if/when the aFileName
contains null characters internally. Then rawContent() instead of
c_str() drops the extra allocation.
xstrncpy() still halts on the input \0 character if it happens early
regardless of whether c_str() or rawContent() is used to supply the
input. And passing it length()+1 safely handles non-terminated input
without an length()+1 byte allocated because xstrncpy ends on the n'th
byte for terminating *dst instead of copying it from input.
PS. appendf() is probably causing a re-allocation as well to grow the
MemBlob. So we are looking at probably three allocations here. If this
exception handler is stable enough now to be worth optimizing we should
probably also look at ways to reserve enough memory for explanatoryText
before putting anything into it.
>> +1 if you update the patch to do the above. +0 otherwise - ie. go ahead
>> with commit if you want, but I'd rather see the fixed caller(s) fixed to
>> use a more long-ish term fix.
> Understood. We disagree regarding the "more long-ish" fix desirability.
>
>
> Thank you,
>
> Alex.
>
> _______________________________________________
> squid-dev mailing list
> squid-dev at lists.squid-cache.org
> http://lists.squid-cache.org/listinfo/squid-dev
More information about the squid-dev
mailing list