COMMAND
esound
SYSTEMS AFFECTED
Those running esound
PROBLEM
Following is based on a FreeBSD-SA-00:45 Security Advisory by
FreeBSD. EsounD is a component of the GNOME desktop environment
which is responsible for multiplexing access to audio devices.
The esound port, versions 0.2.19 and earlier, creates a
world-writable directory in /tmp owned by the user running the
EsounD session, which is used for the storage of a unix domain
socket. A race condition exists in the creation of this socket
which allows a local attacker to cause an arbitrary file or
directory owned by the user running esound to become
world-writable. This can give the attacker access to the victim's
account, or lead to a system compromise if esound is run by root.
The esound port is not installed by default, nor is it "part of
FreeBSD" as such: it is part of the FreeBSD ports collection.
Local users can cause files or directories owned by the target
user to become world-writable when that user runs the esd daemon
(e.g. by starting a GNOME session), allowing a security breach of
that user account (or the entire system if esd is run by root)
If you have not chosen to install the esound port/package, then
your system is not vulnerable to this problem.
SOLUTION
Deinstall the esound port/package, if you have installed it (see
the pkg_delete(1) manual page for more information). Solution is
one of the following:
1) Upgrade your entire ports collection and rebuild the esound
port.
2) Deinstall the old package and install a new package dated
after the correction date, obtained from:
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/audio/esound-0.2.19.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/audio/esound-0.2.19.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-stable/audio/esound-0.2.19.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/audio/esound-0.2.19.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-5-current/audio/esound-0.2.19.tgz
3) download a new port skeleton for the esound port from:
http://www.freebsd.org/ports/
and use it to rebuild the port.
For Linux Mandrake:
Linux-Mandrake 6.0: 6.0/RPMS/esound-0.2.17-3mdk.i586.rpm
6.0/RPMS/esound-devel-0.2.17-3mdk.i586.rpm
6.0/SRPMS/esound-0.2.17-3mdk.src.rpm
Linux-Mandrake 6.1: 6.1/RPMS/esound-0.2.17-3mdk.i586.rpm
6.1/RPMS/esound-devel-0.2.17-3mdk.i586.rpm
6.1/SRPMS/esound-0.2.17-3mdk.src.rpm
Linux-Mandrake 7.0: 7.0/RPMS/esound-0.2.17-3mdk.i586.rpm
7.0/RPMS/esound-devel-0.2.17-3mdk.i586.rpm
7.0/SRPMS/esound-0.2.17-3mdk.src.rpm
Linux-Mandrake 7.1: 7.1/RPMS/esound-0.2.17-3mdk.i586.rpm
7.1/RPMS/esound-devel-0.2.17-3mdk.i586.rpm
7.1/SRPMS/esound-0.2.17-3mdk.src.rpm
For RedHat:
ftp://updates.redhat.com/6.2/alpha/esound-0.2.20-0.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/esound-devel-0.2.20-0.alpha.rpm
ftp://updates.redhat.com/6.2/sparc/esound-0.2.20-0.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/esound-devel-0.2.20-0.sparc.rpm
ftp://updates.redhat.com/6.2/i386/esound-0.2.20-0.i386.rpm
ftp://updates.redhat.com/6.2/i386/esound-devel-0.2.20-0.i386.rpm
ftp://updates.redhat.com/6.2/SRPMS/esound-0.2.20-0.src.rpm
ftp://updates.redhat.com/7.0/i386/esound-0.2.20-1.i386.rpm
ftp://updates.redhat.com/7.0/i386/esound-devel-0.2.20-1.i386.rpm
ftp://updates.redhat.com/7.0/SRPMS/esound-0.2.20-1.src.rpm
For Immunix OS 6.2 (StackGuarded versions of the RedHat packages):
http://www.immunix.org:8080/ImmunixOS/6.2/updates/RPMS/esound-0.2.20-0_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/RPMS/esound-devel-0.2.20-0_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/SRPMS/esound-0.2.20-0_StackGuard.src.rpm
Debian is not affected by this bug; the bug is specific to the
unix domain socket support, which was turned off in stable
(2.2/potato) and unstable (woody) on February 16, 2000. Therefore
neither the current stable or unstable distribution of Debian is
vulnerable to this problem. Debian 2.1 (aka "slink") is also not
vulnerable to this problem; the version of esound in Debian 2.1 is
0.2.6, which predates the buggy unix domain socket code.
For SuSE Linux:
SuSE-7.0: ftp://ftp.suse.com/pub/suse/i386/update/7.0/snd1/esound-0.2.19-15.i386.rpm
ftp://ftp.suse.com/pub/suse/i386/update/7.0/zq1/esound-0.2.19-15.src.rpm
SuSE-6.4: ftp://ftp.suse.com/pub/suse/i386/update/6.4/snd1/esound-0.2.16-75.i386.rpm
ftp://ftp.suse.com/pub/suse/i386/update/6.4/zq1/esound-0.2.16-75.src.rpm
SuSE-6.3: ftp://ftp.suse.com/pub/suse/i386/update/6.3/snd1/esound-0.2.15-21.i386.rpm
ftp://ftp.suse.com/pub/suse/i386/update/6.3/zq1/esound-0.2.15-21.src.rpm
SuSE-7.0: ftp://ftp.suse.com/pub/suse/sparc/update/7.0/snd1/esound-0.2.19-15.sparc.rpm
ftp://ftp.suse.com/pub/suse/sparc/update/7.0/zq1/esound-0.2.19-15.src.rpm
SuSE-6.4: ftp://ftp.suse.com/pub/suse/axp/update/6.4/snd1/esound-0.2.16-75.alpha.rpm
ftp://ftp.suse.com/pub/suse/axp/update/6.4/zq1/esound-0.2.16-75.src.rpm
SuSE-6.3: ftp://ftp.suse.com/pub/suse/axp/update/6.3/snd1/esound-0.2.15-21.alpha.rpm
ftp://ftp.suse.com/pub/suse/axp/update/6.3/zq1/esound-0.2.15-21.src.rpm
SuSE-7.0: ftp://ftp.suse.com/pub/suse/ppc/update/7.0/snd1/esound-0.2.19-16.ppc.rpm
ftp://ftp.suse.com/pub/suse/ppc/update/7.0/zq1/esound-0.2.19-16.src.rpm
SuSE-6.4: ftp://ftp.suse.com/pub/suse/ppc/update/6.4/snd1/esound-0.2.16-75.ppc.rpm
ftp://ftp.suse.com/pub/suse/ppc/update/6.4/zq1/esound-0.2.16-75.src.rpm
Here's a patch that fixes the vulnerability in the esound package
(0.2.19 and prior):
--- esd.h.orig Thu Jun 29 23:12:53 2000
+++ esd.h Thu Jun 29 23:12:41 2000
@@ -7,8 +7,15 @@
#endif
/* path and name of the default EsounD domain socket */
+#if 0
#define ESD_UNIX_SOCKET_DIR "/tmp/.esd"
#define ESD_UNIX_SOCKET_NAME ESD_UNIX_SOCKET_DIR ## "/" ## "socket"
+#else
+char *esd_unix_socket_dir(void);
+char *esd_unix_socket_name(void);
+#define ESD_UNIX_SOCKET_DIR esd_unix_socket_dir()
+#define ESD_UNIX_SOCKET_NAME esd_unix_socket_name()
+#endif
/* length of the audio buffer size */
#define ESD_BUF_SIZE (4 * 1024)
--- esd.c.orig Tue Apr 4 11:20:08 2000
+++ esd.c Thu Jun 29 23:34:18 2000
@@ -219,12 +219,12 @@
{
mkdir(ESD_UNIX_SOCKET_DIR,
S_IRUSR|S_IWUSR|S_IXUSR|
- S_IRGRP|S_IWGRP|S_IXGRP|
- S_IROTH|S_IWOTH|S_IXOTH);
+ S_IRGRP|S_IXGRP|
+ S_IROTH|S_IXOTH);
chmod(ESD_UNIX_SOCKET_DIR,
S_IRUSR|S_IWUSR|S_IXUSR|
- S_IRGRP|S_IWGRP|S_IXGRP|
- S_IROTH|S_IWOTH|S_IXOTH);
+ S_IRGRP|S_IXGRP|
+ S_IROTH|S_IXOTH);
}
if (access(ESD_UNIX_SOCKET_NAME, R_OK | W_OK) == -1)
{
@@ -317,9 +317,9 @@
/* let anyone access esd's socket - but we have authentication so they */
/* wont get far if they dont have the auth key */
chmod(ESD_UNIX_SOCKET_NAME,
- S_IRUSR|S_IWUSR|S_IXUSR|
- S_IRGRP|S_IWGRP|S_IXGRP|
- S_IROTH|S_IWOTH|S_IXOTH);
+ S_IRUSR|S_IWUSR|
+ S_IRGRP|
+ S_IROTH);
}
if (listen(socket_listen,16)<0)
{
--- esdlib.c.orig Thu Jun 29 23:31:04 2000
+++ esdlib.c Thu Jun 29 23:31:21 2000
@@ -19,6 +19,8 @@
#include <arpa/inet.h>
#include <errno.h>
#include <sys/wait.h>
+#include <pwd.h>
+#include <limits.h>
#include <sys/un.h>
@@ -1421,4 +1423,34 @@
*/
return close( esd );
+}
+
+char *
+esd_unix_socket_dir(void) {
+ static char *sockdir = NULL, sockdirbuf[PATH_MAX];
+ struct passwd *pw;
+
+ if (sockdir != NULL)
+ return (sockdir);
+ pw = getpwuid(getuid());
+ if (pw == NULL || pw->pw_dir == NULL) {
+ fprintf(stderr, "esd: could not find home directory\n");
+ exit(1);
+ }
+ snprintf(sockdirbuf, sizeof(sockdirbuf), "%s/.esd", pw->pw_dir);
+ endpwent();
+ sockdir = sockdirbuf;
+ return (sockdir);
+}
+
+char *
+esd_unix_socket_name(void) {
+ static char *sockname = NULL, socknamebuf[PATH_MAX];
+
+ if (sockname != NULL)
+ return (sockname);
+ snprintf(socknamebuf, sizeof(socknamebuf), "%s/socket",
+ esd_unix_socket_dir());
+ sockname = socknamebuf;
+ return (sockname);
}