Re: [PATCH] virt-host-validate: Allow longer list of CPU flags

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

 



On 7/23/24 13:08, Jiri Denemark wrote:
> On Tue, Jul 23, 2024 at 12:41:31 +0200, Michal Privoznik wrote:
>> On various occasions, virt-host-validate parses /proc/cpuinfo to
>> learn about CPU flags (see virHostValidateGetCPUFlags()). It does
>> so, by reading the file line by line until the line with CPU
>> flags is reached. Then the line is split into individual flags
>> (using space as a delimiter) and the list of flags is then
>> iterated over.
>>
>> This works, except for cases when the line with CPU flags is too
>> long. Problem is - the line is capped at 1024 bytes and on newer
>> CPUs (and newer kernels), the line can be significantly longer.
>> I've seen a line that's ~1200 characters long (with 164 flags
>> reported).
>>
>> Switch to unbounded read from the file (getline()).
>>
>> Resolves: https://issues.redhat.com/browse/RHEL-39969
>> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
>> ---
>>  tools/virt-host-validate-common.c | 16 ++++------------
>>  1 file changed, 4 insertions(+), 12 deletions(-)
>>
>> diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
>> index 591143c24d..e5fa6606d2 100644
>> --- a/tools/virt-host-validate-common.c
>> +++ b/tools/virt-host-validate-common.c
>> @@ -106,21 +106,19 @@ virBitmap *virHostValidateGetCPUFlags(void)
>>  {
>>      FILE *fp;
>>      virBitmap *flags = NULL;
>> +    g_autofree char *line = NULL;
>> +    size_t linelen = 0;
>>  
>>      if (!(fp = fopen("/proc/cpuinfo", "r")))
>>          return NULL;
>>  
>>      flags = virBitmapNew(VIR_HOST_VALIDATE_CPU_FLAG_LAST);
>>  
>> -    do {
>> -        char line[1024];
>> +    while (getline(&line, &linelen, fp) > 0) {
>>          char *start;
>>          g_auto(GStrv) tokens = NULL;
>>          GStrv next;
>>  
>> -        if (!fgets(line, sizeof(line), fp))
>> -            break;
>> -
>>          /* The line we're interested in is marked differently depending
>>           * on the architecture, so check possible prefixes */
>>          if (!STRPREFIX(line, "flags") &&
>> @@ -129,12 +127,6 @@ virBitmap *virHostValidateGetCPUFlags(void)
>>              !STRPREFIX(line, "facilities"))
>>              continue;
>>  
>> -        /* fgets() includes the trailing newline in the output buffer,
>> -         * so we need to clean that up ourselves. We can safely access
>> -         * line[strlen(line) - 1] because the checks above would cause
>> -         * us to skip empty strings */
>> -        line[strlen(line) - 1] = '\0';
>> -
> 
> getline() also includes the trailing newline in the buffer (as long as
> there is any newline) and thus we still need to drop it. We just don't
> need to call strlen to compute the length. Although I would suggest
> using a little bit more robust code instead of describing the existing
> code is safe...

good point

> 
>     if (linelen > 1 && line[linelen - 1] == '\n')
>         line[linelen - 1] = '\0';

I'm going with virStringTrimOptionalNewline().


Michal



[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]

  Powered by Linux