Re: [PATCH] nodeinfo: Make sure we always reset errno before calling readdir

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04/10/2014 08:38 AM, Natanael Copa wrote:

>>> -    errno = 0;
>>> -    while ((cpudirent = readdir(cpudir))) {
>>> +    for (errno = 0; (cpudirent = readdir(cpudir)); errno = 0) {
>>>          if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
>>>              continue;
>>
>> Good catch.  However, the code is still buggy even after your fix.  We
>> are missing:
>>
>> if (errno)
>>     break;
>>
>> before attempting the sscanf.
> 
> Why? if readdir fails it should return NULL and the for() loop
> condition should break the loop. If readdir does not return NULL it
> didn't fail and errno value is undefined.

Uggh, you're right.  Yet another reason why I hate the readdir() interface.

> 
> I suppose we could use helper function to make it more readable:
> 
> static struct dirent *virReaddir(DIR *dirp)
> {
>     errno = 0;
>     return readdir(dirp);
> }

Or maybe:

int virReaddir(DIR *dirp, struct dirent **ent)
{
    errno = 0;
    *ent = readdir(dirp);
    if (!*ent && errno) {
        virReportSystemError(errno, _("unable to read directory"))
        return -1;
    }
    return *ent ? 1 : 0;
}

and used as:

while ((ret = virReaddir(dirp, &entry)) > 0) {
    process entry
}
if (ret < 0)
    goto error;


> while ((cpudirent = virReaddir(cpudir))
> 
>> Furthermore, sscanf() is undefined on
>> overflow; while the cpudir is unlikely to be giving us integers that
>> overflow, it would be nicer to not use sscanf in the first place.  It's
>> more than just the improper use of readdir that needs fixing here.
>>
>> I'm debating whether to push this now and fix the rest as a followup, or
>> whether to do a v2 that fixes it all at once.
> 
> I'd say fix the current bug first and do the clean up in separate commit.

Saving sscanf() abuse cleanup for a separate commit is just fine.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]