[Utopia] Updated logging and security patches for hal 0.2.97



Hi David, hi Utopia readers!

I updated my patches for the upstream version 0.2.97. Since it is
tedious to maintain them properly against the rapidly chaning hal
code, would you consider applying at least some of them? Most of the
stuff fixes bugs and is completely independent from privilege dropping
anyway and none of the patches are Debian specific.

01_log_to_syslog.patch: actually log to syslog, not to the void

02_ioctl_errors.patch: intercept unchecked ioctl calls and log
failures

03_drop_privileges.patch: add option --drop-privileges which causes
hald not to run as root, but as @HAL_USER@ in @HAL_GROUP@ and all
additional groups set in /etc/group, and keeping the necessary
capabilities to do its job. This does _not_ change the default
behaviour, if the option is not specified, hald runs as root, as
before.

04_fix_hal_conf_in.patch: replace hardcoded policy user "root" by
"@HAL_USER@".

Thanks for considering and have a nice day!

Martin
-- 
Martin Pitt                 Debian GNU/Linux Developer
martin piware de                      mpitt debian org
http://www.piware.de             http://www.debian.org
--- hal-0.2.93+20040711.orig/hald/logger.c
+++ hal-0.2.93+20040711/hald/logger.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <syslog.h>
 
 #include "logger.h"
 
@@ -53,6 +54,8 @@
 void
 logger_init ()
 {
+    openlog( "hald", 0, LOG_DAEMON );
+
 }
 
 /** Setup logging entry
@@ -83,6 +86,7 @@
 	va_list args;
 	char buf[512];
 	char *pri;
+	int syslog_prio;
 
 	va_start (args, format);
 	vsnprintf (buf, 512, format, args);
@@ -90,25 +94,30 @@
 	switch (priority) {
 	case HAL_LOGPRI_TRACE:
 		pri = "[T]";
+		syslog_prio = LOG_DEBUG;
 		break;
 	case HAL_LOGPRI_DEBUG:
 		pri = "[D]";
+		syslog_prio = LOG_DEBUG;
 		break;
 	case HAL_LOGPRI_INFO:
 		pri = "[I]";
+		syslog_prio = LOG_INFO;
 		break;
 	case HAL_LOGPRI_WARNING:
 		pri = "[W]";
+		syslog_prio = LOG_WARNING;
 		break;
 	default:		/* explicit fallthrough */
 	case HAL_LOGPRI_ERROR:
 		pri = "[E]";
+		syslog_prio = LOG_ERR;
 		break;
 	}
 
 	/** @todo Make programmatic interface to logging */
 	if (priority != HAL_LOGPRI_TRACE)
-		fprintf (stderr, "%s %s:%d %s() : %s\n",
+		syslog (syslog_prio, "%s %s:%d %s() : %s\n",
 			 pri, file, line, function, buf);
 
 	va_end (args);
diff -ru hal-0.2.97.orig/hald/linux/block_class_device.c hal-0.2.97/hald/linux/block_class_device.c
--- hal-0.2.97.orig/hald/linux/block_class_device.c	2004-08-16 20:52:39.000000000 +0200
+++ hal-0.2.97/hald/linux/block_class_device.c	2004-08-30 11:38:38.000000000 +0200
@@ -253,7 +253,8 @@
 	if (fd < 0)
 		return;
 		
-	ioctl (fd, CDROM_SET_OPTIONS, CDO_USE_FFLAGS);
+	if( ioctl (fd, CDROM_SET_OPTIONS, CDO_USE_FFLAGS) < 0 )
+	    HAL_ERROR(("CDROM_SET_OPTIONS failed: %s\n", strerror(errno)));
 		
 	capabilities = ioctl (fd, CDROM_GET_CAPABILITY, 0);
 	if (capabilities < 0) {
@@ -724,6 +725,10 @@
 			got_media = TRUE;
 			break;
 			
+		case -1:
+		    HAL_ERROR(("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)));
+		    break;
+
 		default:
 			break;
 		}
diff -ru hal-0.2.97.orig/hald/linux/input_class_device.c hal-0.2.97/hald/linux/input_class_device.c
--- hal-0.2.97.orig/hald/linux/input_class_device.c	2004-08-15 18:16:37.000000000 +0200
+++ hal-0.2.97/hald/linux/input_class_device.c	2004-08-30 11:37:52.000000000 +0200
@@ -38,6 +38,7 @@
 #include <limits.h>
 #include <fcntl.h>
 #include <linux/input.h>
+#include <errno.h>
 
 #include "../logger.h"
 #include "../device_store.h"
@@ -135,7 +136,8 @@
                 if (ioctl(fd, EVIOCGNAME(sizeof name), name) >= 0) {
                         hal_device_property_set_string (d, "info.product",
                                                         name);
-                }
+                } else
+		    HAL_ERROR(("EVIOCGNAME failed: %s\n", strerror(errno)));
         }
 
         /* @todo add more ioctl()'s here */
diff -ru hal-0.2.97.orig/hald/linux/printer_class_device.c hal-0.2.97/hald/linux/printer_class_device.c
--- hal-0.2.97.orig/hald/linux/printer_class_device.c	2004-07-05 20:21:07.000000000 +0200
+++ hal-0.2.97/hald/linux/printer_class_device.c	2004-08-30 11:37:52.000000000 +0200
@@ -41,6 +41,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
+#include <errno.h>
 
 #include "../logger.h"
 #include "../device_store.h"
@@ -115,7 +116,9 @@
 		   device_id) < 0) {
 		close (fd);
 		return;
-	}
+	} else
+	    HAL_ERROR(("LPIOC_GET_DEVICE_ID failed: %s\n", strerror(errno)));
+
 
 	close (fd);
 
diff -ru hal-0.2.97.orig/hald/hald.c hal-0.2.97/hald/hald.c
--- hal-0.2.97.orig/hald/hald.c	2004-08-15 10:45:48.000000000 +0200
+++ hal-0.2.97/hald/hald.c	2004-08-30 11:40:11.000000000 +0200
@@ -38,6 +38,9 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
+#include <sys/prctl.h>
+#include <sys/capability.h>
+#include <grp.h>
 
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
@@ -161,6 +164,8 @@
 	fprintf (stderr,
 		 "\n"
 		 "        --daemon=yes|no    Become a daemon\n"
+		 "        --drop-privileges  Run as normal user instead of root (calling of external\n"
+		 "                           scripts to modify fstab etc. will not work any more)\n"
 		 "        --help             Show this information and exit\n"
 		 "\n"
 		 "The HAL daemon detects devices present in the system and provides the\n"
@@ -217,6 +222,70 @@
 }
 
 
+
+/** 
+ * Drop all but necessary privileges from hald when it runs as root.  Set the
+ * running user id to 'hal' and groups to 'disk', 'floppy', and 'cdrom'. Drops
+ * all unnecessary capabilities. On error, a message is sent to syslog and
+ * the program terminates with exit code -1.
+ */
+void
+drop_privileges()
+{
+    cap_t cap;
+    struct passwd *pw = NULL;
+    struct group *gr = NULL;
+
+    /* determine user id */
+    pw = getpwnam( HAL_USER );
+    if( !pw )  {
+	HAL_ERROR(( "drop_privileges: user " HAL_USER " does not exist\n" ));
+	exit( -1 );
+    }
+
+    /* determine primary group id */
+    gr = getgrnam( HAL_GROUP );
+    if( !gr ) {
+	HAL_ERROR(( "drop_privileges: group " HAL_GROUP " does not exist\n" ));
+	exit( -1 );
+    }
+
+    /* keep capabilities and change uid/gid */
+    if( prctl( PR_SET_KEEPCAPS, 1, 0, 0, 0 ) ) {
+	HAL_ERROR(( "drop_privileges: could not keep capabilities\n" ));
+	exit( -1 );
+    }
+
+    if( initgroups( HAL_USER, gr->gr_gid ) ) {
+	HAL_ERROR(( "drop_privileges: could not initialize groups\n" ));
+	exit( -1 );
+    }
+
+    if( setgid( gr->gr_gid ) ) {
+	HAL_ERROR(( "drop_privileges: could not set group id\n" ));
+	exit( -1 );
+    }
+
+    if( setuid( pw->pw_uid ) ) {
+	HAL_ERROR(( "drop_privileges: could not set user id\n" ));
+	exit( -1 );
+    }
+
+    /* only keep necessary capabilities */
+    cap = cap_from_text( "cap_net_admin=ep" );
+
+    if( cap_set_proc( cap ) ) {
+	HAL_ERROR(( "drop_privileges: could not install capabilities\n" ));
+	exit( -1 );
+    }
+
+    if( cap_free( cap ) ) {
+	HAL_ERROR(( "drop_privileges: cap_free\n" ));
+	exit( -1 );
+    }
+}
+
+
 /** Entry point for HAL daemon
  *
  *  @param  argc                Number of arguments
@@ -236,6 +305,7 @@
 		static struct option long_options[] = {
 			{"daemon", 1, NULL, 0},
 			{"help", 0, NULL, 0},
+			{"drop-privileges", 0, NULL, 0},
 			{NULL, 0, NULL, 0}
 		};
 
@@ -260,7 +330,8 @@
 					usage ();
 					return 1;
 				}
-			}
+			} else if (strcmp(opt, "drop-privileges") == 0)
+			    drop_privileges ();
 			break;
 
 		default:
Nur in hal-0.2.97/hald: hald.c.orig.
diff -ru hal-0.2.97.orig/hald/Makefile.am hal-0.2.97/hald/Makefile.am
--- hal-0.2.97.orig/hald/Makefile.am	2004-08-15 20:18:53.000000000 +0200
+++ hal-0.2.97/hald/Makefile.am	2004-08-30 11:40:11.000000000 +0200
@@ -73,7 +73,7 @@
 	linux/volume_id/volume_id.h	linux/volume_id/volume_id.c	\
 	linux/drive_id/drive_id.h	linux/drive_id/drive_id.c
 
-hald_LDADD = @PACKAGE_LIBS@
+hald_LDADD = @PACKAGE_LIBS@ -lcap
 
 #### Init scripts fun
 SCRIPT_IN_FILES=haldaemon.in
Nur in hal-0.2.97/hald: Makefile.am.orig.
--- hal-0.2.93+20040711.orig/hal.conf.in
+++ hal-0.2.93+20040711/hal.conf.in
@@ -9,7 +9,7 @@
 
   <!-- Only user @HAL_USER@ can own the HAL service and be an agent -->
   <!-- policy user="@HAL_USER@" We require root to sniff mii registers -->
-  <policy user="root">
+  <policy user="@HAL_USER@">
     <allow own="org.freedesktop.Hal"/>
 
     <allow send_interface="org.freedesktop.Hal.AgentManager"
@@ -28,7 +28,7 @@
 
   <!-- Any user in the @HAL_GROUP@ group can use the AgentManager interface -->
   <!-- policy group="@HAL_GROUP@" Doesn't work on dbus 0.20. Works in CVS -->
-  <policy user="root">
+  <policy user="@HAL_USER@">
     <allow send_interface="org.freedesktop.Hal.AgentManager"
            send_destination="org.freedesktop.Hal"/>
     <allow receive_interface="org.freedesktop.Hal.AgentManager"

Attachment: signature.asc
Description: Digital signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]