RFR (XS): 8199010: attachListener.hpp: Fix potential null termination issue found by coverity scans

Chris Plummer chris.plummer at oracle.com
Mon Mar 5 22:37:42 UTC 2018

On 3/5/18 1:28 PM, Langer, Christoph wrote:
> Hi Chris,
>> Asserts imply something that is suppose to never happen, but that you
>> want to check for in debug builds to help uncover bugs. Given this,
>> either we have a bug (and someone can pass in a name that is too long),
>> or coverity is complaining about something that can never happen, or the
>> assert is invalid. So the potential fixes are:
>> -Fix the problem up the call chain were the invalid string can be passed in.
>> -Tell coverity to clam up because having the string be too long is not
>> possible.
>> -Leave in your fix but remove the assert.
> I believe coverity has a valid point here for the case that strlen(name) == name_length_max or strlen(arg) == arg_length_max. In that case, memcpy would copy exactly the bytes for the strings without the terminating zero. And as zero initialization of c++ members is not guaranteed (as far as I know), the name_length_max + 1 byte or arg_legth_max + 1 could theoretically have nonzero values.
> Furthermore, I think in this case it makes sense to have an assertion because, as you state, in the debug builds you want to see any potential bug uncovered at the cost of a JVM exit. But in an opt build you want to be rather stable, even in case you get names and arguments passed that are too long. I don't want to go into the details of potential calling paths how that can happen, though... But even in case there are length violations in attach operation names or its arguments, the operations would most likely result in no success which is uncritical to a running VM.
> So wouldn't you agree that my change is fine as is?
> Submission-repo testing reported no errors.
> Best regards
> Christoph
Hi Christoph,

We don't assert things that we also explicitlydefend against.For 
example, the following defensive coding should not be accepted:

     // x is never suppose to be less then 0, but just in case it is, 
set it to 0
     assert(x >= 0);
     if (x < 0) x = 0;

Either it can't be less then zero and we assert this, or we accept the 
possibility that it could be less then zero and defend against it, but 
no assert in that case.

Given the following initial code (and ignoring what coverity might have 
to say about it):

  127     memcpy(_name, name, MIN2(len + 1, (size_t)name_length_max));

I would argue that the bug here is that it should be:

  127     memcpy(_name, name, MIN2(len, (size_t)name_length_max) + 1);

Maybe this would silence coverity, but it also is the correct thing to 
do. We weren't null terminating if len == name_length_max because we 
were only copying len bytes in that case, not len+1. But, this still has 
the issue of defending against something we also assert for, so the 
reality is the MIN2 part should be be needed at all. Does coverity 
complain if you get rid of it?

  127     memcpy(_name, name, len + 1);



More information about the hotspot-runtime-dev mailing list