Bug 165270

Summary: buffer overflow detected
Product: [Fedora] Fedora Reporter: Bill Crawford <billcrawford1970>
Component: xscreensaverAssignee: Ray Strode [halfline] <rstrode>
Status: CLOSED RAWHIDE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: jwz, valdis.kletnieks
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-08-24 17:27:35 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:
Attachments:
Description Flags
backtrace output from xscreensaver
none
Another backtrace
none
valgrind output for xscreensaver-demo
none
backtrace with xscreensaver-/glibc-/gtk2-debuginfo none

Description Bill Crawford 2005-08-06 10:08:45 UTC
Description of problem:
see attached traceback

Version-Release number of selected component (if applicable):
xscreensaver-base-4.22-5

Comment 1 Bill Crawford 2005-08-06 10:08:46 UTC
Created attachment 117508 [details]
backtrace output from xscreensaver

Comment 2 Bill Crawford 2005-08-06 10:38:34 UTC
(as the map list in the traceback shows, this is actually xscreensaver-demo,
spawned from xscreensaver to update the preferences file to indicate the last
saver run, when changing from one saver to another)

Comment 3 Bill Crawford 2005-08-09 11:39:01 UTC
I first noticed this because I opened the "properties" page from the gnome
xscreensaver button on the top panel, intending to find out what the last hack
displayed had been, and it was showing a GL hack selected that I had disabled a
few days previously and so should not have been running; looking in the output
log I create (by running startx -- -layout huge >X.log 2>&1) showed the
backtrace I attached.

I'm now getting a crash of xscreensaver-demo every time I try to enable or
disable any hack, and the backtrace is very similar (somewhere under
write_init_file).


Comment 4 Bill Crawford 2005-08-09 11:40:14 UTC
Created attachment 117569 [details]
Another backtrace

Comment 5 Jamie Zawinski 2005-08-12 02:08:23 UTC
Can you reproduce this under valgrind (and preferably when compiled with -g) so that I can tell where this 
is happening?  I can't reproduce it on my FC4 machine.

Comment 6 Bill Crawford 2005-08-12 07:20:24 UTC
It may be a glibc bug. Watch with me as I run the unstripped version under gdb:

Program received signal SIGABRT, Aborted.
0x009c9402 in __kernel_vsyscall ()
(gdb) up
#1  0x00c44858 in raise () from /lib/libc.so.6
(gdb) up
#2  0x00c45fc8 in abort () from /lib/libc.so.6
(gdb) up
#3  0x00c7996a in __libc_message () from /lib/libc.so.6
(gdb) up
#4  0x00cfa3d5 in __chk_fail () from /lib/libc.so.6
(gdb) up
#5  0x00cfaa00 in __realpath_chk () from /lib/libc.so.6
(gdb) up
#6  0x0804e566 in chase_symlinks (file=0x961c860 "/home/bill/.xscreensaver")
    at /usr/include/bits/stdlib.h:35
35          return __realpath_chk (__name, __resolved, __bos (__resolved));


Comment 7 Bill Crawford 2005-08-12 07:21:42 UTC
I'll attach the valgrind output anyway, later, when bugzilla stops giving me
"Internal server error" every time I try :)

Comment 8 Bill Crawford 2005-08-12 07:40:40 UTC
Created attachment 117669 [details]
valgrind output for xscreensaver-demo

shows same backtrace, and an amusing bit of output from the bowels of Xt

Comment 9 Jamie Zawinski 2005-08-18 03:51:27 UTC
Beats me... I can't tell what's going on from what you attached.  I don't get that on my FC4 machine.

The Xt stuff is typical, though, and almost certainly not the problem.

Comment 10 Frank Arnold 2005-08-19 07:36:03 UTC
Created attachment 117899 [details]
backtrace with xscreensaver-/glibc-/gtk2-debuginfo

I get the same on a recent ppc rawhide installation with
xscreensaver-base-4.22-7 and 166299 looks like another duplicate.

Comment 11 Bill Crawford 2005-08-24 10:23:25 UTC
It's something in __bowels_of_glibc.  driver/prefs.c`write_init_file calls
ditto`chase_symlinks which calls realpath() and then there's a crash ... I've
just cut out the code in chase_symlinks (except for the "return 0;") so that the
damn thing works, for now.  There's a 2K buffer being passed in, and I know
there aren't any symlinks in the path to .xscreensaver on here.

Comment 12 Ray Strode [halfline] 2005-08-24 12:23:41 UTC
> /usr/lib/libgtk-x11-2.0.so.0[0x88b706]
> /usr/lib/libgtk-x11-2.0.so.0(gtk_tree_selection_select_path+0xa9)[0x88bca9]
> /usr/lib/libgtk-x11-2.0.so.0(gtk_tree_selection_select_iter+0x71)[0x88bd54]

This might be related to bug 166299. 

Do you still see the problem with xscreensaver-base-4.22-8 ?

Comment 13 Bill Crawford 2005-08-24 15:23:13 UTC
Yes (so I've modified the source now).

It fails during the call to realpath().

I'm gonna take a guess: the buffer passed is on the stack, and the "buffer
overflow" check in glibc is just seeing an address above the bottom of the stack
and punting?

This started happening after one of the glibc updates in Rawhide.


Comment 14 Valdis Kletnieks 2005-08-24 16:09:54 UTC
xscreensaver-base-4.22-8 still fails.  glibc-2.3.90-9 here, since it looks like
it might be a glibc issue.  I don't know how long it's been broken, sorry.

Comment 15 Ray Strode [halfline] 2005-08-24 17:27:35 UTC
I think this should be fixed in xscreensaver-base-4.22-9 in tomorrow's rawhide.
 The problem is realpath expects a buffer to be passed to it of size PATH_MAX
and xscreensaver was passing a buffer of size 2048.  since xscreensaver was just
strdup'ing the result anyway, I changed it to pass NULL for realpath which will
cause it to automatically allocate enough space for the file path.

Comment 16 Jamie Zawinski 2005-08-25 02:11:20 UTC
Is that portable behavior for realpath()?  It's not documented in the man page on either FC4 or OSX.  In 
fact, the FC4 man page says:

       EINVAL Either path or resolved_path is NULL. (In libc5 this would just
              cause a segfault.)

I imagine this is a more portable fix:

--- prefs.c	18 Apr 2005 01:05:10 -0000	1.42
+++ prefs.c	25 Aug 2005 02:08:04 -0000
@@ -86,7 +86,14 @@
 # ifdef HAVE_REALPATH
   if (file)
     {
-      char buf [2048];
+# ifndef PATH_MAX
+#  ifdef MAXPATHLEN
+#   define PATH_MAX MAXPATHLEN
+#  else
+#   define PATH_MAX 2048
+#  endif
+# endif
+      char buf[PATH_MAX];
       if (realpath (file, buf))
         return strdup (buf);
 


Comment 17 Ray Strode [halfline] 2005-08-25 14:02:09 UTC
Hi Jaime,

realpath() is just unportable in general.

Your way is more portable than mine, but some platforms require doing something
like:

long max_path_length = pathconf (file, _PC_PATH_MAX);

to get the maximum path length.  Furthermore, pathconf can return -1 to mean "no
max path limit" or it can return an absurdly high number that you wouldn't want
to pass to malloc.  In either of those two case there is no safely sized buffer
you can pass to realpath.  

Passing NULL is a glibc extension.  I don't know what other c libraries support it.

Using a fallback size at all is risky, but if you're going to use one I'd say
pick 4096 instead of 2048, because 2048 is what caused this bug to be opened in
the first place.


Comment 18 Bill Crawford 2005-08-25 14:54:01 UTC
Check for canonicalize_file_name() (it's "equivalent," it says, "to the call
realpath(path, NULL)."  If that exists, problem solved.

Otherwise, if realpath() exists and PATH_MAX is defined, use that.

Else, punt, and skip it (or write one, but that seems a little pointless).

You could call pathconf() and test the result to be sure it's somewhere between
0 and, say, 64K.