1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-13 19:22:58 +00:00

fix potential segfault

The segfault can be triggered by using any diskio object with a
non-existent device, as prepare_diskio_stat() then returns 0 and the
call to obj->data.diskio->current in conky.c:4050 pulls the trigger.

In fact, it's not a problem when the device doesn't exist, as
update_diskio() simply won't fill in any values. So skip the check and
upon device node appearance everything goes it's normal way.

While there, also eliminate double readout of the last line of
/proc/diskstats: after the last line has been read, FEOF is not yet set.
BUT fgets() will return NULL when trying to read the next line. So
better check for fgets()'s return value instead of using feof().

Also strncmp() is useless here, since we really want to compare the full
paths. Besides, text_buffer_size also should be big enough to not make a
difference here.
This commit is contained in:
Phil Sutter 2008-12-25 15:06:38 +01:00
parent 65c27816c4
commit a619cb3e3c

View File

@ -66,10 +66,6 @@ struct diskio_stat *prepare_diskio_stat(const char *s)
{
struct diskio_stat *new = 0;
unsigned i;
FILE *fp;
int found = 0;
char device[text_buffer_size], fbuf[text_buffer_size];
static int rep = 0;
if (!s)
return &diskio_stats[0];
@ -95,32 +91,6 @@ struct diskio_stat *prepare_diskio_stat(const char *s)
new->dev = 0;
}
new->dev = strndup(s, text_buffer_size);
/*
* check that device actually exists
*/
if (!(fp = open_file("/proc/diskstats", &rep))) {
ERR("cannot read from /proc/diskstats");
return 0;
}
while (!feof(fp)) {
fgets(fbuf, text_buffer_size, fp);
if (sscanf(fbuf, "%*u %*u %255s %*u %*u %*u %*u %*u %*u %*u", device)) {
// check for device match
if (strncmp(new->dev, device, 256) == 0) {
found = 1;
break;
}
}
}
fclose(fp);
fp = 0;
if (!found) {
ERR("diskio device '%s' does not exist", s);
return 0;
}
new->current = 0;
new->current_read = 0;
new ->current_write = 0;
@ -156,8 +126,7 @@ void update_diskio(void)
/* read reads and writes from all disks (minor = 0), including cd-roms
* and floppies, and sum them up */
while (!feof(fp)) {
fgets(buf, 512, fp);
while (fgets(buf, 512, fp)) {
col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u", &major,
&minor, devbuf, &reads, &writes);
/* ignore subdevices (they have only 3 matching entries in their line)
@ -177,8 +146,7 @@ void update_diskio(void)
}
}
for (i = 1; i < MAX_DISKIO_STATS; i++) {
if (diskio_stats[i].dev &&
strncmp(devbuf, diskio_stats[i].dev, text_buffer_size) == 0) {
if (diskio_stats[i].dev && !strcmp(devbuf, diskio_stats[i].dev)) {
diskio_stats[i].current =
(reads + writes - diskio_stats[i].last) / 2;
diskio_stats[i].current_read =