[libvirt] [PATCH v2 2/6] openvz: Resolve Coverity FORWARD_NULL
John Ferlan
jferlan at redhat.com
Wed Oct 7 13:56:54 UTC 2015
On 10/07/2015 02:14 AM, Peter Krempa wrote:
> On Fri, Sep 25, 2015 at 12:31:41 -0400, John Ferlan wrote:
>> Coverity complains that strtok_r cannot be called if the first and third
>> parameters are NULL. On entry if the 'value' parameter is not checked for
>> being NULL before the VIR_STRDUP which will set the target to NULL if
>> the source (eg value) is NULL. Thus add a check for NULL value.
>>
>> NB: Although each of the callers to openvzParseBarrierLimit would only
>> make the call when 'value' was non-NULL, it seems that doesn't satisfy
>> the checker. The NULL check had to be in this funtion.
>
> Erm, so then file a bug against coverity rather than hacking around it?
>
Even doing that will take "time" for them to fix and even when fixed
doesn't mean it works in our build environment.
Besides I didn't have success in generating a "small reproducer".
The last time I logged a bug against Coverity was with the VIR_FREE()
ternary operation. That was "fixed"; however, if I remove the change
from the code and build, it seems for 95% of the cases the claim of
RESOURCE_LEAK has gone away, but a few of these type FORWARD_NULL's
now appear. My guess is the ternary in strtok_r is what's causing the
issue. That guess is based on experience of looking at Coverity issues
from trace around the issue:
(5) Event cond_true: Condition "1", taking true branch
(6) Event cond_true: Condition "(size_t)(void const *)&":"[1] - (size_t)(void const *)":" == 1", taking true branch
(7) Event cond_true: Condition "(char const *)":"[0] != 0", taking true branch
(8) Event cond_true: Condition "(char const *)":"[1] == 0", taking true branch
(9) Event var_deref_model: Passing "&saveptr" to "__strtok_r_1c", which dereferences null "saveptr". [details]
and the "details" for the error that Coverity links one to, where events
(5) - (8) seems to come from:
1137 #if !defined _HAVE_STRING_ARCH_strtok_r || defined _FORCE_INLINES
1138 # ifndef _HAVE_STRING_ARCH_strtok_r
1139 # define __strtok_r(s, sep, nextp) \
1140 (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
1141 && ((const char *) (sep))[0] != '\0' \
1142 && ((const char *) (sep))[1] == '\0' \
1143 ? __strtok_r_1c (s, ((const char *) (sep))[0], nextp) \
1144 : __strtok_r (s, sep, nextp)))
1145 # endif
1146
1147 __STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
1148 __STRING_INLINE char *
1149 __strtok_r_1c (char *__s, char __sep, char **__nextp)
...
Remember that Coverity tries "every" path... I'm still not sure why
some strtok_r calls are "ok" while others aren't. I believe it mostly
has to do with where it's done. Perhaps virStringSplit* type calls
would also solve these...
>>
>> Signed-off-by: John Ferlan <jferlan at redhat.com>
>> ---
>> src/openvz/openvz_conf.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
>> index fb8768a..e99b83c 100644
>> --- a/src/openvz/openvz_conf.c
>> +++ b/src/openvz/openvz_conf.c
>> @@ -135,10 +135,10 @@ openvzParseBarrierLimit(const char* value,
>> {
>> char *token;
>> char *saveptr = NULL;
>> - char *str;
>> + char *str = NULL;
>> int ret = -1;
>>
>> - if (VIR_STRDUP(str, value) < 0)
>> + if (!value || VIR_STRDUP(str, value) < 0)
>
> VIR_STRDUP returns 0 if @value was NULL so you can as well as test for <
> 1. Since then the value gets initialized to NULL you don't need the
> first hunk.
>
If I change to :
if (VIR_STRDUP(str, value) <= 0)
it doesn't help - so it's something about checking !value that keeps Coverity quiet.
That !value check also must be done in the same function as the strtok_r,
so that lends even more credence to my belief about the ternary.
>> goto error;
>>
>> token = strtok_r(str, ":", &saveptr);
>> @@ -396,7 +396,7 @@ openvzReadFSConf(virDomainDefPtr def,
>> param = "DISKSPACE";
>> ret = openvzReadVPSConfigParam(veid, param, &temp);
>> if (ret > 0) {
>> - if (openvzParseBarrierLimit(temp, &barrier, &limit)) {
>> + if (openvzParseBarrierLimit(temp, &barrier, &limit) < 0) {
>> virReportError(VIR_ERR_INTERNAL_ERROR,
>> _("Could not read '%s' from config for container %d"),
>> param, veid);
>
> This change should be mentioned in the commit message since it's
> different from what the current message says.
>
I forgot about this line... Not that it will matter as I'll just abandon this
change and just filter it in my local build.
John
More information about the libvir-list
mailing list