Bug 95830 - URL completion causes SIGBUS on Solaris
Summary: URL completion causes SIGBUS on Solaris
Status: RESOLVED FIXED
Alias: None
Product: kio
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Solaris
: NOR normal
Target Milestone: ---
Assignee: Michael Pyne
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-12-26 04:54 UTC by Michael Pyne
Modified: 2004-12-28 17:48 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Potential fix to the problem by overallocating memory. (1.27 KB, patch)
2004-12-26 05:17 UTC, Michael Pyne
Details
Patch we are currently using (881 bytes, patch)
2004-12-27 06:32 UTC, The Written Word
Details
v2 (1016 bytes, patch)
2004-12-27 06:49 UTC, The Written Word
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Pyne 2004-12-26 04:54:54 UTC
Version:            (using KDE KDE 3.3.2)
Installed from:    Compiled From Sources
Compiler:          gcc 3.4.3 
OS:                Solaris

Reported by Albert Chin in a mail to kde-devel:

"We have qt-3.3.2, kdelibs-3.3.2, and kdebase-3.3.2 built with -g on
Solaris 8/SPARC with gcc-3.4.3. If we File->Open in kate and, in the
Location text box, press "/", the File->Open dialog disappears."

He eventually tracked that down to what I consider to be a bug in some UNIX systems headers, but we can work around it without too much effort, so I'm opening this bug report to remove the discussion for kde-devel.
Comment 1 Michael Pyne 2004-12-26 04:56:53 UTC
The bug itself is that on at least Solaris and IRIX, the struct dirent as defined in the system header files aren't defined large enough to be initialized by readdir_r(), thus causing a SIGBUS.  I'm working on a patch now.
Comment 2 Michael Pyne 2004-12-26 05:17:32 UTC
Created attachment 8815 [details]
Potential fix to the problem by overallocating memory.

This patch allocates (sizeof (struct dirent) + PATH_MAX) bytes of memory (and
frees it when done), which should hopefully fix the bug.  I've tested the patch
here in KDE HEAD and it seems to work correctly.  Reporter: please try the
patch and let me know if it works.
Comment 3 The Written Word 2004-12-27 06:32:11 UTC
There is a problem with your patch:
+		struct dirent *dirPosition = ( struct dirent * ) ::malloc(
+		               sizeof( struct dirent * ) + PATH_MAX );

You should take sizeof( struct dirent ). Also, shouldn't you add +1 for the trailing '\0'? I've attached the patch we are using. It was inspired by a similar patch by Stefan Teleman, who makes a Solaris version of KDE available.

The Solaris sturct dirent is:
typedef struct dirent {
        ino_t           d_ino;          /* "inode number" of entry */
        off_t           d_off;          /* offset of disk directory entry */
        unsigned short  d_reclen;       /* length of this record */
        char            d_name[1];      /* name of file */
} dirent_t;

So, maybe because d_name is already allocated to one byte, we can drop the +1 for the trailing '\0'?
Comment 4 The Written Word 2004-12-27 06:32:48 UTC
Created attachment 8823 [details]
Patch we are currently using
Comment 5 The Written Word 2004-12-27 06:48:58 UTC
BTW, we use MAXPATHLEN rather than _PATH_MAX because MAXPATHLEN is used in other place in kdelibs.
Comment 6 The Written Word 2004-12-27 06:49:57 UTC
Created attachment 8824 [details]
v2

Updated patch to include <sys/param.h> for MAXPATHLEN
Comment 7 Michael Pyne 2004-12-27 16:57:12 UTC
> There is a problem with your patch: 
>  + struct dirent *dirPosition = ( struct dirent * ) ::malloc( 
>  +                sizeof( struct dirent * ) + PATH_MAX ); 

Uh, yeah, let's keep that between you, me, and kde-bugs-dist. ;)  That's such a rookie mistake it's scary. :(

As far as your patch goes, it looks good except for minor stylistic issues regarding the comment spacing.  I'm assuming that it works on your system since you're submitting it.  I'll test it here and then maybe run it by wheels before committing to kdelibs.
Comment 8 The Written Word 2004-12-28 06:13:54 UTC
I've tested the patch on Solaris 2.6-9/SPARC, HP-UX 11.x, Tru64 UNIX 5.1, IRIX 6.5, Redhat Linux 7.1, 9, and RHEL 2.1, 3.0.
Comment 9 Michael Pyne 2004-12-28 17:41:28 UTC
CVS commit by mpyne: 

Fix bug 95830 (URL completion causes SIGBUS on Solaris) in CVS.

Will backport to 3.3.

CCBUG:95830


  M +8 -2      kurlcompletion.cpp   1.71


--- kdelibs/kio/kio/kurlcompletion.cpp  #1.70:1.71
@@ -56,4 +56,5 @@
 #include <pwd.h>
 #include <time.h>
+#include <sys/param.h>
 
 #include "kurlcompletion.h"
@@ -220,9 +221,12 @@ void DirectoryListThread::run()
 
                 // Loop through all directory entries
+                // Solaris and IRIX dirent structures do not allocate space for d_name. On
+                // systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but
+                // that's ok.
 
-                struct dirent dirPosition;
+                struct dirent *dirPosition = (struct dirent *) malloc( sizeof( struct dirent ) + MAXPATHLEN + 1 );
                 struct dirent *dirEntry = 0;
                 while ( !terminationRequested() &&
-                        ::readdir_r( dir, &dirPosition, &dirEntry ) == 0 && dirEntry )
+                        ::readdir_r( dir, dirPosition, &dirEntry ) == 0 && dirEntry )
                 {
                         // Skip hidden files if m_noHidden is true
@@ -282,4 +286,6 @@ void DirectoryListThread::run()
                 ::closedir( dir );
                 dir = 0;
+
+                free( dirPosition );
         }
 


Comment 10 Michael Pyne 2004-12-28 17:48:13 UTC
CVS commit by mpyne: 

Fix bug 95830 (URL completion causes SIGBUS on Solaris) in KDE 3.3.

Thanks to the bug reporter for investigating the issue (*coughSolariscough*)
and for the patch.

BUG:95830


  M +8 -2      kurlcompletion.cpp   1.67.2.1


--- kdelibs/kio/kio/kurlcompletion.cpp  #1.67:1.67.2.1
@@ -55,4 +55,5 @@
 #include <pwd.h>
 #include <time.h>
+#include <sys/param.h>
 
 #include "kurlcompletion.h"
@@ -219,9 +220,12 @@ void DirectoryListThread::run()
 
                 // Loop through all directory entries
+                // Solaris and IRIX dirent structures do not allocate space for d_name. On
+                // systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but
+                // that's ok.
 
-                struct dirent dirPosition;
+                struct dirent *dirPosition = (struct dirent *) malloc( sizeof( struct dirent ) + MAXPATHLEN + 1 );
                 struct dirent *dirEntry = 0;
                 while ( !terminationRequested() &&
-                        ::readdir_r( dir, &dirPosition, &dirEntry ) == 0 && dirEntry )
+                        ::readdir_r( dir, dirPosition, &dirEntry ) == 0 && dirEntry )
                 {
                         // Skip hidden files if m_noHidden is true
@@ -281,4 +285,6 @@ void DirectoryListThread::run()
                 ::closedir( dir );
                 dir = 0;
+
+                free( dirPosition );
         }