RFR(M): 8140482: Various minor code improvements (runtime)
Markus Gronlund
markus.gronlund at oracle.com
Thu Nov 5 10:15:10 UTC 2015
Hi Goetz,
Thanks for suggesting these fixes.
Also thanks for pointing to the issue with _NSIG and MAXSIGNUM - looks like MAXSIGNUM is defined all over the place (platform specific + platform specific jsig's)...
I also think it makes perfect sense to bound the signals to the dimensions of the arrays where they will be stored (sigact[MAXSIGNUM] and sigflags[MAXSIGNUM]).
SR_initialize() will (after optionally fetching the env variable for SR_signum) eventually call into:
void os::Linux::set_our_sigflags() {
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
sigflags[sig] = flags;
}
This assert makes me question the expression in SR_initialize():
if (sig > 0 || sig < _NSIG) { <<----
SR_signum = sig;
}
Due to shortcutting there is no upper bound range check on the signal here. If _NSIG is larger than MAXSIGNUM this could be a significant problem.
Should most likely be changed to:
(sig > 0 && sig < MAXSIGNUM)
Thanks
Markus
-----Original Message-----
From: David Holmes
Sent: den 4 november 2015 10:29
To: Lindenmaier, Goetz; hotspot-runtime-dev at openjdk.java.net; serviceability-dev
Subject: Re: RFR(M): 8140482: Various minor code improvements (runtime)
On 4/11/2015 6:01 PM, Lindenmaier, Goetz wrote:
> Hi David,
>
> attachListener.hpp:
> I agree that I can not find another possible issue with the strcpy.
> Still I think it's better to have the strncpy, as it would have
> protected against the bug in attachListener_windows.cpp.
> But if you insist I'll just remove it.
I don't insist, but I do prefer to place all the guards at the "boundary" of the VM rather than at every level when possible.
> Should I remove the _NSIG issue from this change and open an issue of
> it's own discussed on the serviceability list?
Let's give them a chance to respond. I'll ping them on the hotline ;-)
Thanks,
David
> Best regards,
> Goetz.
>
>
>> -----Original Message-----
>> From: David Holmes [mailto:david.holmes at oracle.com]
>> Sent: Mittwoch, 4. November 2015 08:15
>> To: Lindenmaier, Goetz; hotspot-runtime-dev at openjdk.java.net;
>> serviceability-dev
>> Subject: Re: RFR(M): 8140482: Various minor code improvements
>> (runtime)
>>
>> Hi Goetz,
>>
>> On 4/11/2015 12:10 AM, Lindenmaier, Goetz wrote:
>>> Hi David,
>>>
>>> the new scan is already through. I made a new webrev:
>>> http://cr.openjdk.java.net/~goetz/webrevs/8140482-covRt/webrev.01/
>>>
>>> attachListener_linux.cpp:
>>> I had moved the string termination out of the loop, and read one
>>> less char from the file. The scan still claims "Passing unterminated
>>> string buf to strlen" in line 274. So I will undo it again for the
>>> webrev.
>>>
>>> codeBuffer.cpp
>>> Doing memset is fine. I'll use memset().
>>>
>>>>>>> ps_core.c:
>>>>>>> Pread not necessarily terminates interp_name which is printed
>>>>>>> thereafter. Increase buffer size by 1 and add '\0'.
>>>>>>
>>>>>> Given:
>>>>>> #define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
>>>>>> isn't it impossible to encounter that problem?
>>>>> As I understand, pread does not null-terminate what it read. So
>>>>> the null must come from the file. This protects against a corrupted file.
>>>>
>>>> So are you saying the nul is not present in the file? I'm not
>>>> familiar with the ELF format.
>>> There should be a nul in the file, else the code would fail more
>>> obviously. The problem is if the file is corrupted.
>>
>> Thanks for clarifying.
>>
>> I'm still unclear why the attachListener.hpp changes are needed if we
>> have validated the entry points in the attachListener_<os>.cpp files?
>>
>> Also we still need someone from serviceability to comment on the
>> _NSIG issue.
>>
>> Thanks,
>> David
>>
>>
>>> Best regards,
>>> Goetz.
>>>
>>>
>>>> -----Original Message-----
>>>> From: David Holmes [mailto:david.holmes at oracle.com]
>>>> Sent: Dienstag, 3. November 2015 11:07
>>>> To: Lindenmaier, Goetz; hotspot-runtime-dev at openjdk.java.net;
>>>> serviceability-dev
>>>> Subject: Re: RFR(M): 8140482: Various minor code improvements
>> (runtime)
>>>>
>>>> Hi Goetz,
>>>>
>>>> Quick follow up on a couple of things ...
>>>>
>>>> On 3/11/2015 7:33 PM, Lindenmaier, Goetz wrote:
>>>>> Hi David,
>>>>>
>>>>>> Sorry, lots of folks very busy at the moment as we try to get
>>>>>> features finalized before the deadline.
>>>>> thanks for looking at this! I know the Dec. 10 deadline, but I
>>>>> guess that
>> also
>>>>> holds for us ... at least J1 is over now. (Unfortunately we could
>>>>> not
>> attend
>>>>> this year.)
>>>>
>>>> Me neither :)
>>>>
>>>>>>> ps_core.c:
>>>>>>> Pread not necessarily terminates interp_name which is printed
>>>> thereafter.
>>>>>>> Increase buffer size by 1 and add '\0'.
>>>>>>
>>>>>> Given:
>>>>>> #define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
>>>>>> isn't it impossible to encounter that problem?
>>>>> As I understand, pread does not null-terminate what it read. So
>>>>> the null must come from the file. This protects against a corrupted file.
>>>>
>>>> So are you saying the nul is not present in the file? I'm not
>>>> familiar with the ELF format.
>>>>
>>>>>>> stubRoutines_x86.cpp:
>>>>>>> Cast to proper type. This way, left and right of '&' have the same type.
>>>>>>
>>>>>> I think you could just have changed the uint64_t to uint32_t as
>>>>>> applied to the shift rather than casting the 1 to uint_32t. End
>>>>>> result is the same though.
>>>>> What you propose did not work. It was my first fix, too.
>>>>
>>>> Hmm okay. The result of the shift must be an unsigned type and the
>>>> constant 1 is signed, so needs the cast (or use the unsigned
>>>> constant form - 1ud? )
>>>>
>>>>>>> attachListener_linux.cpp:
>>>>>>> Read does not terminate buf. Size for '\0' is already considered.
>>>>>>
>>>>>> Looks a little odd being done on each iteration, but okay I guess.
>>>>> I'll try to move it out of the loop. Better: I'll check whether
>>>>> the scan groks it if I move it out of the loop :)
>>>>>
>>>>>>> os_linux.cpp:
>>>>>>> Array sigflags[] has size MAXSIGNUM==32. _NSIG is bigger than
>>>>>>> MAXSIGNUM (_NSIG == 65 on my machine).
>>>>>>> sig is checked to be smaller than _NSIG. Later, in
>>>>>>> set_our_sigflags(), sig is used to access sigflags[MAXSIGNUM]
>>>>>>> which can overflow the
>> array.
>>>>>>> Should we also increase MAXSIGNUM?
>>>>>>
>>>>>> Need to let the SR folk comment here as something definitely
>>>>>> seems wrong, but I'm not 100% sure the what the correct answer
>>>>>> is. If _JAVA_SR_SIGNUM is too big it should be validated
>>>>>> somewhere and
>> an
>>>> error
>>>>>> or warning reported.
>>>>> I'm also not sure how to best handle this. Might even require a
>>>>> fix exceeding this change. But I think this is the best finding.
>>>>>
>>>>>>> codeBuffer.cpp:
>>>>>>> New_capacity is not initialized. Figure_expanded_capacities()
>>>>>>> handles
>>>> this
>>>>>>> correctly, but initializing this is cheap and safe.
>>>>>>
>>>>>> Hmmm ... I hate redundancy - this is pure wasted cycles. If we
>>>>>> had to
>> do
>>>>>> it would memset not be better? Or would the code-checker not
>>>>>> realize what memset was doing?
>>>>> I guess it would work with memset, too. But I thought the 3-deep
>>>>> loop will be unrolled completely so that only three stores remain.
>>>>
>>>> I tend not to try and imagine what the compiler may or may not do.
>>>> Happy to take other opinions. Though again I'd prefer if the
>>>> checker could be shown that there is no missing initialization.
>>>>
>>>>>>> dict.cpp:
>>>>>>> If j-- is executed for j==0, the loop aborts because j is
>>>>>>> unsigned (0-- >=
>> b-
>>>>>>> _cnt).
>>>>>>> Instead, only do j++ if necessary.
>>>>>>
>>>>>> Not at all obvious to me that it is possible to do j-- when j==0,
>>>>>> but the change seems reasonable.
>>>>> Yes, the scan does not understand there is j++ right after j--
>>>>> because of the loop iteration. I saw it complaining about this
>>>>> pattern several
>> times.
>>>>>
>>>>>> Lots of spacing changes in that code make it hard to see the real
>> changes.
>>>>> Before, I was asked to fix indentation issues in a function I touch.
>>>>> Does that only hold for compiler files?
>>>>
>>>> Yes/no/maybe :) Fixing up bad formatting when you are touching an
>>>> area can be convenient, however it can also obscure the real
>>>> changes, so it depends on the ratio of functional changes to format changes.
>>>>
>>>>>> 145 // SAPJVM GL j-- can underflow, which will cause the loop to
>> abort.
>>>>>> Seems unnecessary with the code change as noone will understand
>> what
>>>> j--
>>>>>> you are referring to.
>>>>> Didn't mean to leave this in here. Removed.
>>>>>
>>>>>> 150 nb->_keyvals[nbcnt + nbcnt ] = key;
>>>>>> 151 nb->_keyvals[nbcnt + nbcnt + 1] = b->_keyvals[j+j+1];
>>>>>> hotspot-style doesn't align array index expressions like that.
>>>>>> Ditto 154/155.
>>>>> Fixed.
>>>>>
>>>>>>> generateOopMap.cpp:
>>>>>>> Idx is read from String. This is only called with constant
>>>>>>> strings, so
>>>> compare
>>>>>>> should be folded away by optimizing compilers if inlined.
>>>>>>
>>>>>> Not a fan of adding conditions that should never be false (hence
>>>>>> the
>>>>>> assert) and relying on the compiler to elide them.
>>>>> OK, removed.
>>>>>
>>>>>>> deoptimization.cpp:
>>>>>>> If buflen == 0, buf[-1] is accessed.
>>>>>>
>>>>>> Okay - but an assert(buflen>0) would be better I think as we
>>>>>> should never be calling with a zero-length buffer.
>>>>> Ok, I added the assert. As this isn't critical code, I would like
>>>>> to leave the check in there, still.
>>>>>
>>>>>>> task.cpp:
>>>>>>> Fatal can return if -XX:SuppressErrorAt is used. Just don't
>>>>>>> access the array in this case.
>>>>>>
>>>>>> Okay. I would not be surprised if we have a lot of potential
>>>>>> errors if a fatal/guarantee failure is suppressed.
>>>>>>
>>>>>>> attachListener.hpp:
>>>>>>> Do strncpy to not overflow buffer. Don't write more chars than
>> before.
>>>>>>
>>>>>> Again we have the assert to catch an error in the caller using an
>>>>>> invalid name.
>>>>> Hmm, the command comes from outside of the VM. It's not checked
>>>>> very thoroughly, see, e.g., attachListener_windows.cpp:194. Arg0
>>>>> is checked twice, arg1 and arg2 are not checked at all.
>>>>
>>>> The libattach code is still part of our codebase so should be doing
>>>> the right things. The linux and solaris code seems to be doing the
>>>> expected name length check. On Windows the name is set using cmd,
>>>> which is also subject to a length check:
>>>>
>>>> if (strlen(cmd) > AttachOperation::name_length_max) return
>>>> ATTACH_ERROR_ILLEGALARG;
>>>>
>>>>> I add fixes for attachListener_windows.cpp to this change.
>>>>>
>>>>>>> heapDumper.cpp:
>>>>>>> strncpy does not null terminate.
>>>>>>
>>>>>> 1973 if (total_length >= sizeof(base_path)) {
>>>>>>
>>>>>> total_length already adds +1 for the nul character so the == case
>>>>>> is fine AFAICS.
>>>>>>
>>>>>> strncpy wont nul-terminate if the string exceeds the buffer size.
>>>>>> But
>> we
>>>>>> have already established that total_length <= sizeof(base_path),
>>>>>> and total_path includes space for a bunch of stuff other than
>> HeapDumpPath,
>>>>>> so the strncpy of HeapDumpPath has to copy the nul character.
>>>>> Ok, removed.
>>>>>
>>>>>> > src/share/vm/services/memoryService.cpp
>>>>>>
>>>>>> Ok.
>>>>>>
>>>>>> > src/share/vm/utilities/xmlstream.cpp
>>>>>>
>>>>>> Ok - I'm more concerned about the "magic" 10 in that piece of code.
>>>>> I assume the 10 is the space needed for the "_done" plus some waste ...
>>>>>
>>>>> I'll do another run of the scan. That takes a day. I'll post a
>>>>> new webrev
>>>> after
>>>>> that.
>>>>
>>>> Thanks,
>>>> David
>>>>
>>>>> Thank again for this thorough review,
>>>>> Goetz
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> Some of these, as the issue in codeBuffer.cpp, are actually
>>>>>>> handled
>>>> correctly.
>>>>>>> Nevertheless this is not that obvious so that somebody changing
>>>>>>> the
>>>> code
>>>>>>> Could oversee he has to add the initialization.
>>>>>>
>>>>>> Not an argument I buy en-masse as it leads to a lot of redundancy
>>>>>> through the code paths. Plus these tools that are being run
>>>>>> should
>> show
>>>>>> if a code changes requires initialization that is not present.
>>>>>>
>>>>>> Thanks,
>>>>>> David
>>>>>>
>>>>>>> Some of these fixes are part of SAP JVM for a long time. This
>>>>>>> change
>> has
>>>>>>> been tested with our nightly build of openJDK.
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Goetz,.
>>>>>>>
More information about the serviceability-dev
mailing list