[libvirt] [PATCH 2/5] commandtest: Resolve some coverity resource leaks

John Ferlan jferlan at redhat.com
Thu Feb 14 19:00:35 UTC 2013


On 02/14/2013 12:43 PM, Eric Blake wrote:
> On 02/14/2013 10:15 AM, Peter Krempa wrote:
>> On 02/14/13 17:42, John Ferlan wrote:
>>> ---
>>>   tests/commandtest.c | 17 ++++++++++++-----
>>>   1 file changed, 12 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/tests/commandtest.c b/tests/commandtest.c
>>> index 93c6333..3bfc358 100644
>>> --- a/tests/commandtest.c
>>> +++ b/tests/commandtest.c
>>
>> ...
>>
>>> @@ -963,16 +964,19 @@ mymain(void)
>>>           dup2(fd, 6) < 0 ||
>>>           dup2(fd, 7) < 0 ||
>>>           dup2(fd, 8) < 0 ||
>>> -        (fd > 8 && VIR_CLOSE(fd) < 0))
>>> +        (fd > 8 && VIR_CLOSE(fd) < 0)) {
>>> +        VIR_FORCE_CLOSE(fd);
>>>           return EXIT_FAILURE;
>>> +    }
>>> +    sa_assert(fd == -1);
>>
>> according to man of dup2():
>> *  If  oldfd  is a valid file descriptor, and newfd has the same value
>> as oldfd, then dup2() does nothing, and returns newfd.
>>
>> It is possible that open returns fd < 8, dup2() on that does nothing and
>> afterwards this assertion won't be true.
> 
> I gave my ACK too soon - Peter is right that fd _might_ not be -1 at
> this point.  There are two cases to consider:
> 
> 1. start life with fds 3-8 already opened by inheritance (rare). Opening
> /dev/null gets fd 9, which we then dup to 3-8 (overwriting whatever was
> inherited from the environment), then we close 9.  If we fail to dup2,
> we still close 9, but none of the other fds which we forcefully
> overwrote.  In this case, fd==-1 is true when you get to the sa_assert.
> 
> 2. start life with at least one of fd 3-8 closed (most common).  Opening
> /dev/null then gets the first open fd, which we then dup to all the
> remaining fds between 3-8.  We don't close fd in this case, because we
> want fds 3-8 opened on /dev/null; so in this case, fd==-1 is false.
> 
> Does the assert actually fix anything?  I think it is best to remove it.
> 

Without the sa_assert, the following is coughed up by Coverity:

979  	
980  	    /* Phase two of killing interfering fds; see above.  */

(20) Event overwrite_var: 	Overwriting handle "fd" in "fd = 3" leaks the
handle.
Also see events:
[open_fn][var_assign][noescape][noescape][noescape][noescape][noescape][noescape]

981  	    fd = 3;
982  	    VIR_FORCE_CLOSE(fd);

When I first modified this code it was still fd 3->5 being dup2'd and
the sa_assert() worked for at least shutting coverity up, but I see the
point about the last if condition.

So, one could logically believe the check could change to:

    sa_assert(fd == -1 || (fd >= 3 && fd <= 8));

but that too triggers Coverity to complain that we're overwriting the
fd. So without creating a new variable and adding more busy work, adding
the following prior to the initialization removes the warning.


    /* coverity[overwrite_var] - silence the obvious */
    fd = 3;


Also, yes, it's strange on the error case of the if condition that one
doesn't have to do the same close 3->8 game even though the
VIR_FORCE_CLOSE(fd) was needed.

>>
>>>
>>>       /* Prime the debug/verbose settings from the env vars,
>>>        * since we're about to reset 'environ' */
>>>       ignore_value(virTestGetDebug());
>>>       ignore_value(virTestGetVerbose());
>>>
>>> -    if (virInitialize() < 0)
>>> -        return EXIT_FAILURE;
>>> +    /* Make sure to not leak fd's */
>>> +    virinitret = virInitialize();
>>>
>>>       /* Phase two of killing interfering fds; see above.  */
>>>       fd = 3;
>>
>> ACK with the assertion removed or a sufficient explanation provided.
>>
>> Peter
>>
>> -- 
>> libvir-list mailing list
>> libvir-list at redhat.com
>> https://www.redhat.com/mailman/listinfo/libvir-list
>>
>>
> 




More information about the libvir-list mailing list