Bug 145998

Summary: kudzu segfaults if /etc/sysconfig/mouse is empty
Product: [Fedora] Fedora Reporter: Kalev Lember <kalevlember>
Component: kudzuAssignee: Bill Nottingham <notting>
Status: CLOSED RAWHIDE QA Contact: David Lawrence <dkl>
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: rvokal
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: 1.1.113-1 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-04-22 17:34:43 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 136451    

Description Kalev Lember 2005-01-24 16:58:53 UTC
My problem is that kudzu segfaults if size of /etc/sysconfig/mouse is 0.

There is a function:
char *bufFromFd(int fd)
in kudzu.c, that does fstat and if the file size is 0, it returns a
null pointer. Null pointer is returned, because
read(fd, tmpbuf, sizeof(tmpbuf)) > 0
is never true if file size is 0:

        fstat(fd,&sbuf);
        if (sbuf.st_size) {
                buf = malloc(sbuf.st_size + 1);
                memset(buf,'\0',sbuf.st_size + 1);
                read(fd, buf, sbuf.st_size);
                buf[sbuf.st_size] = '\0';
        } else {
                memset(tmpbuf,'\0', sizeof(tmpbuf));
                while (read(fd, tmpbuf, sizeof(tmpbuf)) > 0) {
                        buf = realloc(buf, bytes + sizeof(tmpbuf));
                        memcpy(buf + bytes, tmpbuf, sizeof(tmpbuf));
                        bytes += sizeof(tmpbuf);
                        memset(tmpbuf, '\0', sizeof(tmpbuf));
                }
        }


I see no point in the while loop, because it is never run in case
sbuf.st_size is 0.

Everywhere where bufFromFd is used, the return values are not checked.
If it returns null pointer, it is usually dereferenced.
An example of null pointer dereference in hwconf.c:
   buf = bufFromFd(fd);
   tmp = strstr(buf,"DEVICE=");

One way would be to check (!buf) everywhere where bufFromFd is used.

A quick hack would be:

diff -u -p -r1.135 kudzu.c
--- kudzu.c     6 Jan 2005 17:37:27 -0000       1.135
+++ kudzu.c     24 Jan 2005 16:38:04 -0000
@@ -578,8 +578,6 @@ static int devCmp( const void *a, const
 char *bufFromFd(int fd) {
        struct stat sbuf;
        char *buf = NULL;
-       unsigned long bytes = 0;
-       char tmpbuf[16384];

        fstat(fd,&sbuf);
        if (sbuf.st_size) {
@@ -588,13 +586,7 @@ char *bufFromFd(int fd) {
                read(fd, buf, sbuf.st_size);
                buf[sbuf.st_size] = '\0';
        } else {
-               memset(tmpbuf,'\0', sizeof(tmpbuf));
-               while (read(fd, tmpbuf, sizeof(tmpbuf)) > 0) {
-                       buf = realloc(buf, bytes + sizeof(tmpbuf));
-                       memcpy(buf + bytes, tmpbuf, sizeof(tmpbuf));
-                       bytes += sizeof(tmpbuf);
-                       memset(tmpbuf, '\0', sizeof(tmpbuf));
-               }
+               buf = strdup("");
        }
        close(fd);
        return buf;


Steps to Reproduce:
rm -f /etc/sysconfig/mouse
touch /etc/sysconfig/mouse
kudzu -s

crashes here

Comment 1 Bill Nottingham 2005-04-22 17:34:43 UTC
The loop is there because files in /proc have size 0. :/

Fixed in 1.1.112-1. 

Comment 2 Bill Nottingham 2005-04-22 22:25:55 UTC
Oops, 1.1.113-1.