Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Wed, 06 Feb 2013 17:48:59 +0100
From: Sebastian Pipping <sebastian@...ping.org>
To: oss-security@...ts.openwall.com
Subject: CVE request: Insecure default log file path in xNBD

Hello oss-security!


Target software
===============

xNBD upstream
   https://bitbucket.org/hirofuchi/xnbd

Official Debian packages
   http://packages.debian.org/sid/xnbd-server


Description
===========

xnbd-server (and xnbd-wrapper in some releases) use /tmp/xnbd.log
for logging when parameter --daemonize (and no --logpath FILE) is given.

The file is opened using flags O_WRONLY | O_CREAT | O_APPEND so there
is a vulnerability against symlinks attacks.


Demonstration
=============

Here is an exploitation example:

   $ ln -s "${HOME}"/ATTACK_TARGET /tmp/xnbd.log

   $ touch DISK
   $ truncate --size=$((100*1024**2)) DISK

   $ /usr/sbin/xnbd-server --daemonize --target DISK
   xnbd-server(12462) msg: daemonize enabled
   xnbd-server(12462) msg: cmd target mode
   xnbd-server(12462) msg: disk DISK size 104857600 B (100 MB)
   xnbd-server(12462) msg: xnbd master initialization done
   xnbd-server(12462) msg: logfile /tmp/xnbd.log

   $ ls -l ~/ATTACK_TARGET
   -rw------- 1 user123 user123 653 Feb  1 16:41 \
     /home/user123/ATTACK_TARGET


Affected versions
=================

The latest code in the upstream Mercurial repository is not affected
since it does not use logging to /tmp/xnbd.log (or any default
location) any more.

----------------------------------------------------------------------
   Version                        Status
----------------------------------------------------------------------
   0.0.x                          not analyzed
   0.1.0-pre                      VULNERABLE (xnbd-server only)
   0.1.0-pre-hg20-e75b93a47722-2  VULNERABLE (xnbd-server and -wrapper)
   Mercurial tip                  not vulnerable
----------------------------------------------------------------------


Options for a fix
=================

  a) Use syslog with --daemonize and no default file location in general
     (i.e. what upstream did)

  b) Use /var/log/xnbd-server.log and /var/log/xnbd-wrapper.log
     for the hard-coded defaults

  c) Replace flag O_APPEND by O_EXCL  (secure but reducing functionality)

The attached patch applies approach (b) to version 
0.1.0-pre-hg20-e75b93a47722.


Best,



Sebastian

>From 3774432cdb8e6a2cf6183d496ad7a2678883b592 Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@...ping.org>
Date: Tue, 5 Feb 2013 14:05:29 +0100
Subject: [PATCH] Fix insecure logging location (CVE-FILL_ME)

---
 trunk/doc/xnbd-server.8.sgml  |    2 +-
 trunk/doc/xnbd-wrapper.8.sgml |    2 +-
 trunk/xnbd_common.c           |   11 +++++------
 trunk/xnbd_common.h           |    6 ++----
 trunk/xnbd_server.c           |    9 +++++----
 trunk/xnbd_wrapper.c          |   10 +++++++---
 6 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/trunk/doc/xnbd-server.8.sgml b/trunk/doc/xnbd-server.8.sgml
index 6033a17..63c65fe 100644
--- a/trunk/doc/xnbd-server.8.sgml
+++ b/trunk/doc/xnbd-server.8.sgml
@@ -172,7 +172,7 @@ manpage.1: manpage.sgml
         <term><option>--logpath <replaceable>FILE</replaceable></option>
         </term>
         <listitem>
-          <para>Log informational messages to the given <replaceable>FILE</replaceable> if given. Defaults to <replaceable>/tmp/xnbd.log</replaceable></para>
+          <para>Log informational messages to the given <replaceable>FILE</replaceable> if given. Defaults to <replaceable>/var/log/xnbd-server.log</replaceable></para>
         </listitem>
       </varlistentry>
 
diff --git a/trunk/doc/xnbd-wrapper.8.sgml b/trunk/doc/xnbd-wrapper.8.sgml
index 1eae7a5..67d080d 100644
--- a/trunk/doc/xnbd-wrapper.8.sgml
+++ b/trunk/doc/xnbd-wrapper.8.sgml
@@ -126,7 +126,7 @@ manpage.1: manpage.sgml
         <term><option>--logpath <replaceable>FILE</replaceable></option>
         </term>
         <listitem>
-          <para>Log informational messages to the given <replaceable>FILE</replaceable> if given. Defaults to <replaceable>/tmp/xnbd.log</replaceable></para>
+          <para>Log informational messages to the given <replaceable>FILE</replaceable> if given. Defaults to <replaceable>/var/log/xnbd-wrapper.log</replaceable></para>
         </listitem>
       </varlistentry>
 
diff --git a/trunk/xnbd_common.c b/trunk/xnbd_common.c
index cb3cff0..186e646 100644
--- a/trunk/xnbd_common.c
+++ b/trunk/xnbd_common.c
@@ -197,9 +197,9 @@ unsigned long get_disk_nblocks(off_t disksize)
 	return (unsigned long) nblocks64;
 }
 
-void redirect_stderr(const char *logfile)
+void redirect_stderr(const char *logfile, const char * default_logfile)
 {
-        int logfd = open(logfile ? logfile : DEFAULT_XNBDSERVER_LOGFILE,
+        int logfd = open(logfile ? logfile : default_logfile,
                          O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
         if (logfd < 0)
                 err("open %s, %m", logfile);
@@ -211,7 +211,7 @@ void redirect_stderr(const char *logfile)
         close(logfd);
 }
 
-void detach(const char *logpath)
+void detach(const char *logpath, const char * default_logpath)
 {
         close(STDIN_FILENO);
 
@@ -224,9 +224,8 @@ void detach(const char *logpath)
         close(devnull);
 
         if(!logpath) {
-                logpath = DEFAULT_XNBDSERVER_LOGFILE;
-                info("logfile %s", logpath);
-                redirect_stderr(logpath);
+                info("logfile %s", default_logpath);
+                redirect_stderr(NULL, default_logpath);
         }
 
         int ret = daemon(0, 1);
diff --git a/trunk/xnbd_common.h b/trunk/xnbd_common.h
index 28e0b32..440f1d7 100644
--- a/trunk/xnbd_common.h
+++ b/trunk/xnbd_common.h
@@ -1,9 +1,7 @@
 #ifndef XNBD_COMMON_H
 #define XNBD_COMMON_H
 
-#define DEFAULT_XNBDSERVER_LOGFILE "/tmp/xnbd.log"
-
-void redirect_stderr(const char *logfile);
-void detach(const char *logpath);
+void redirect_stderr(const char *logfile, const char * default_logfile);
+void detach(const char *logpath, const char * default_logpath);
 
 #endif
diff --git a/trunk/xnbd_server.c b/trunk/xnbd_server.c
index d07502b..dae80d2 100644
--- a/trunk/xnbd_server.c
+++ b/trunk/xnbd_server.c
@@ -29,6 +29,7 @@
 #include <netinet/ip.h>
 
 
+#define XNBD_SERVER_LOGFILE_DEFAULT "/var/log/xnbd-server.log"
 
 
 
@@ -750,7 +751,7 @@ Options: \n\
   --lport	listen port (default 8520)\n\
   --daemonize	run as a daemon process\n\
   --readonly	export a disk as readonly\n\
-  --logpath	logfile (default /tmp/xnbd.log)\n\
+  --logpath	logfile (default /var/log/xnbd-server.log)\n\
   --inetd	redirect stderr for running from inetd\n\
 ";
 
@@ -825,7 +826,7 @@ int main(int argc, char **argv) {
 	}
 
 	if (inetd)
-		redirect_stderr(logpath);
+		redirect_stderr(logpath, XNBD_SERVER_LOGFILE_DEFAULT);
 
 	optind = 1;
 
@@ -994,11 +995,11 @@ int main(int argc, char **argv) {
 
 	if (!inetd && logpath) {
 		info("logfile %s", logpath);
-		redirect_stderr(logpath);
+		redirect_stderr(logpath, XNBD_SERVER_LOGFILE_DEFAULT);
 	}
 
 	if (daemonize)
-		detach(logpath);
+		detach(logpath, XNBD_SERVER_LOGFILE_DEFAULT);
 
 
 	master_server(lport, (void *) &xnbd, connected_fd);
diff --git a/trunk/xnbd_wrapper.c b/trunk/xnbd_wrapper.c
index d48eb00..fb3a977 100644
--- a/trunk/xnbd_wrapper.c
+++ b/trunk/xnbd_wrapper.c
@@ -27,6 +27,10 @@
 #include <sys/signalfd.h>
 #include <sys/epoll.h>
 
+
+#define XNBD_WRAPPER_LOGFILE_DEFAULT "/var/log/xnbd-wrapper.log"
+
+
 /* static const int MAX_DISKIMG_NUM = 32; */
 #define MAX_DISKIMG_NUM 32
 
@@ -367,7 +371,7 @@ int main(int argc, char **argv) {
 				       "  --xnbd-binary Path to xnbd-server.\n"
 				       "  --imgfile     Path to disk image file. This options can be used multiple times.\n"
 				       "                You can also use xnbd-wrapper-ctl to (de)register disk images dynamically.\n"
-				       "  --logpath     logfile (default /tmp/xnbd.log)\n"
+				       "  --logpath     logfile (default /var/log/xnbd-wrapper.log)\n"
 				       "  --laddr       Listen address.\n"
 				       "  --socket      Unix socket path to listen on (default: /tmp/xnbd_wrapper.ctl).\n"
 				       "\n"
@@ -405,12 +409,12 @@ int main(int argc, char **argv) {
 
 	if (logpath) {
 		info("logfile %s", logpath);
-		redirect_stderr(logpath);
+		redirect_stderr(logpath, XNBD_WRAPPER_LOGFILE_DEFAULT);
         }
 
 
         if (daemonize)
-		detach(logpath);
+		detach(logpath, XNBD_WRAPPER_LOGFILE_DEFAULT);
 
 
 	list_diskimg(&dsklist, stdout);
-- 
1.7.10.4


Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ