[squid-dev] [RFC] Support concurrent SBuf::c_str() calls

Alex Rousskov rousskov at measurement-factory.com
Thu Sep 29 16:03:43 UTC 2016


Hello,

    The current trunk code contains at least two serious bugs caused by
SBuf::c_str() misuse. Both known bugs looks similar:

> storeCreateEntry(storeUri.c_str(), storeUri.c_str(), ...);

and

> storeCreateEntry(uri.c_str(), uri.c_str(), ...);


Both use cases violate safe c_str() use conditions documented in the
long and occasionally YELLING description of that method. As you have
probably guessed by now, the c_str() method itself is not constant, so
calling c_str() twice often destroys the first c_str() result.

It is trivial to fix both violations, but it is very difficult to say
how many other similar violations are hidden in (or will be added to)
the code. I am sure we will continue to miss them during code reviews.

This particular problem is caused by the "used storage size" increment
in the SBuf::c_str() implementation:

>     *rawSpace(1) = '\0'; // terminate the buffer
>     ++store_->size; // protect the terminator character

The increment forces the second call to c_str() to re-allocate the
store, which usually destroys the still-in-use storage pointed to by the
first c_str() result.

If we remove the increment, then Squid will work as expected when using
two concurrent c_str() results.

With or without the increment, Squid may crash or misbehave when buggy
code appends to SBuf while a previous c_str() result is still in use:
With an increment, appending may destruct the previous c_str() buffer.
Without an increment, appending may overwrite the 0-terminator used by
the previous c_str() call.

Valgrind is able to detect the "concurrent c_str()s" bugs in the current
trunk. My Valgrind tests did not expose other related bugs when I
removed the increment, but that does not mean those other bugs do not
exist, of course.

Should we remove the increment to make concurrent c_str() calls safe?


Thank you,

Alex.


More information about the squid-dev mailing list