Subject: bad mmap64 implementation in esddsp
Package: esound
Version: 0.2.36-3
Severity: important

Hello,
  after few hours of investigation to discover why firefox/iceweasel get
a SIGBUS when I want to save an image, I hope I found the primary cause
of this problem.  It is due to an implementation bug in mmap64 which is
overriden in libesddsp.so.
In effect, mmap64 uses a 64 bits offset (off64_t). However, wrap_mmap
declares a 32 bits one (off_t), at least on 32 bits OS. Therefore, when
calling original mmap64, 32 bits from offset are taken randomly from
stack which could lead to mapping a non existent part of a file in
memory thus signaling a Bus Error when further trying to access to this
mapped memory!

The patch attached work at least on my system (Linux x86 32 bits) but
need more testing on other arches (especially 64 bits ones).
I also applied mutex patch from Ubuntu 0.2.36-3ubuntu2:
http://www.no-name-yet.com/patches/esound.esddsp-crash.patch .

I guess #350428, #348938 and #347751 could be related to this bug.
Surely some bugs from iceweasel package are also related to this one.

Best regards,
Eric.

-- System Information:
Debian Release: 4.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-4-k7
Locale: [EMAIL PROTECTED], [EMAIL PROTECTED] (charmap=ISO-8859-15)

Versions of packages esound depends on:
ii  esound-common               0.2.36-3     Enlightened Sound Daemon - Common
ii  libaudiofile0               0.2.6-6      Open-source version of SGI's audio
ii  libc6                       2.3.6.ds1-13 GNU C Library: Shared libraries
ii  libesd-alsa0 [libesd0]      0.2.36-3     Enlightened Sound Daemon (ALSA) -
ii  libwrap0                    7.6.dbs-13   Wietse Venema's TCP wrappers libra

-- 
 Eric Delaunay       | Le travail est trop sérieux pour le confier
 [EMAIL PROTECTED] | à ceux qui veulent se tuer avec.    Jissey.
diff -ur esound-0.2.36.orig/esddsp.c esound-0.2.36/esddsp.c
--- esound-0.2.36.orig/esddsp.c 2007-03-21 12:45:34.000000000 +0100
+++ esound-0.2.36/esddsp.c      2007-03-21 12:37:13.000000000 +0100
@@ -46,6 +46,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <stdio.h>
+#include <pthread.h>
 
 #ifdef HAVE_MACHINE_SOUNDCARD_H
 #  include <machine/soundcard.h>
@@ -127,10 +128,12 @@
   write (mixfd, &vol, sizeof (vol));
 }
 
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void
 dsp_init (void)
 {
+  pthread_mutex_lock(&mutex);
   if (!ident)
     {
       const char *str;
@@ -162,6 +165,7 @@
          DPRINTF ("mixer settings file: %s\n", mixer);
        }
     }
+  pthread_mutex_unlock(&mutex);
 }
 
 static void
@@ -559,21 +563,25 @@
 }
 
 typedef void *(*mmap_funcptr_t) (void *, size_t, int, int, int, off_t);
+typedef void *(*mmap64_funcptr_t) (void *, size_t, int, int, int, off64_t);
 
 void *
-wrap_mmap (const char *symname, mmap_funcptr_t *func, void *start, 
-                size_t length, int prot, int flags, int fd, off_t offset)
+wrap_mmap (const char *symname, int off64, mmap_funcptr_t *func, void *start, 
+                size_t length, int prot, int flags, int fd, off64_t offset)
 {
   if (!*func)
     *func = (mmap_funcptr_t) dlsym (REAL_LIBC, symname);
 
   if(fd != sndfd || sndfd == -1)
-    return (**func)(start,length,prot,flags,fd,offset);
+    if (off64)
+      return (**(mmap64_funcptr_t*)func)(start,length,prot,flags,fd,offset);
+    else
+      return (**func)(start,length,prot,flags,fd,(off_t)offset);
   else
     {
       DPRINTF ("esddsp: %s - start = %x, length = %d, prot = %d\n",
               symname, start, length, prot);
-      DPRINTF ("      flags = %d, fd = %d, offset = %d\n",flags, fd,offset);
+      DPRINTF ("      flags = %d, fd = %d, offset = %lld\n",flags, fd,offset);
       if(mmapemu)
        {
          mmapemu_osize = length;
@@ -590,15 +598,15 @@
 mmap (void *start, size_t length, int prot, int flags, int fd, off_t offset)
 {
   static mmap_funcptr_t func = NULL;
-  return wrap_mmap("mmap", &func, start, length, prot, flags, fd, offset);
+  return wrap_mmap("mmap", 0, &func, start, length, prot, flags, fd, 
(off64_t)offset);
 }
 
 #ifdef HAVE_MMAP64
 void *
-mmap64 (void *start, size_t length, int prot, int flags, int fd, off_t offset)
+mmap64 (void *start, size_t length, int prot, int flags, int fd, off64_t 
offset)
 {
   static mmap_funcptr_t func = NULL;
-  return wrap_mmap("mmap64", &func, start, length, prot, flags, fd, offset);
+  return wrap_mmap("mmap64", 1, &func, start, length, prot, flags, fd, offset);
 }
 #endif
 

Reply via email to