changeset 10659:933eae95189d

6855341 hald and hald-addon-network-discovery crash
author Xiaolin Zhang - Sun Microsystems - Beijing China <Xiao-Lin.Zhang@Sun.COM>
date Sun, 27 Sep 2009 11:48:10 +0800
parents b6d8a8316c41
children 8ff949139766
files usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c usr/src/cmd/hal/hald/hald_dbus.c usr/src/cmd/hal/hald/util.c usr/src/cmd/hal/hald/util.h
diffstat 4 files changed, 80 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c	Sun Sep 27 11:34:46 2009 +0800
+++ b/usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c	Sun Sep 27 11:48:10 2009 +0800
@@ -1,11 +1,10 @@
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  * Licensed under the Academic Free License version 2.1
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -198,8 +197,11 @@
 	} else if (dbus_message_is_method_call(message,
 				DBUS_INTERFACE, "DisablePrinterScanningViaSNMP")) {
 		rc = nds_DisablePrinterScanningViaSNMP(ctx);
-	} else
+	} else {
+		/* bypass not-handled messages */
 		HAL_WARNING(("Unknown DBus message: %s, %s ", member, path));
+		return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+	}
 
 	if (dbus_error_is_set(&error))
 		dbus_error_free(&error);
--- a/usr/src/cmd/hal/hald/hald_dbus.c	Sun Sep 27 11:34:46 2009 +0800
+++ b/usr/src/cmd/hal/hald/hald_dbus.c	Sun Sep 27 11:48:10 2009 +0800
@@ -3264,6 +3264,7 @@
 	DBusConnection *conn;
 	gchar *exp_name = NULL;
 	gchar *exp_detail = NULL;
+	gboolean invalid_name = FALSE;
 
 	hald_exec_method_process_queue (d->udi);
 
@@ -3287,6 +3288,16 @@
 		}
 		dbus_message_unref (reply);
 	} else if (exp_name != NULL && exp_detail != NULL) {
+		if (!is_valid_interface_name (exp_name)) {
+			/*
+			 * error name may be invalid,
+			 * if so we need a generic HAL error name;
+			 * otherwise, dbus will be messed up.
+			 */
+			invalid_name = TRUE;
+			exp_detail = g_strconcat (exp_name, " \n ", exp_detail, NULL);
+			exp_name = "org.freedesktop.Hal.Device.UnknownError";
+		}
 		reply = dbus_message_new_error (message, exp_name, exp_detail);
 		if (reply == NULL) {
 			/* error name may be invalid - assume caller fucked up and use a generic HAL error name */
@@ -3319,6 +3330,8 @@
 		dbus_message_unref (reply);
 	}
 
+	if (invalid_name)
+		g_free (exp_detail);
 	dbus_message_unref (message);
 }
 
--- a/usr/src/cmd/hal/hald/util.c	Sun Sep 27 11:34:46 2009 +0800
+++ b/usr/src/cmd/hal/hald/util.c	Sun Sep 27 11:48:10 2009 +0800
@@ -54,6 +54,23 @@
 
 #include "util.h"
 
+/** Determine whether the given character is valid as the first character
+ *  in a name.
+ */
+#define VALID_INITIAL_NAME_CHARACTER(c)          \
+	(((c) >= 'A' && (c) <= 'Z') ||           \
+	((c) >= 'a' && (c) <= 'z') ||            \
+	((c) == '_'))
+
+/** Determine whether the given character is valid as a second or later
+ *  character in a name.
+ */
+#define VALID_NAME_CHARACTER(c)                  \
+	(((c) >= '0' && (c) <= '9') ||           \
+	((c) >= 'A' && (c) <= 'Z') ||            \
+	((c) >= 'a' && (c) <= 'z') ||            \
+	((c) == '_'))
+
 gboolean 
 hal_util_remove_trailing_slash (gchar *path)
 {
@@ -1095,3 +1112,45 @@
 
 	g_slist_free (children);
 }
+
+/** Given an interface name, check if it is valid.
+ *  @param  name	A given interface name
+ *  @return		TRUE if name is valid, otherwise FALSE
+ */
+gboolean
+is_valid_interface_name(const char *name) {
+
+	const char *end;
+	const char *last_dot;
+
+	last_dot = NULL;
+
+	if (strlen(name) == 0)
+		return FALSE;
+
+	end = name + strlen(name);
+
+	if (*name == '.')    /* disallow starting with a . */
+		return FALSE;
+	else if (!VALID_INITIAL_NAME_CHARACTER (*name))
+		return FALSE;
+	else
+		name++;
+
+	while (name != end) {
+		if (*name == '.') {
+			if ((name + 1) == end)
+				return FALSE;
+			else if (!VALID_INITIAL_NAME_CHARACTER (*(name + 1)))
+				return FALSE;
+			last_dot = name;
+			name++;    /* we just validated the next char, so skip two */
+		} else if (!VALID_NAME_CHARACTER (*name))
+			return FALSE;
+		name++;
+	}
+	if (last_dot == NULL)
+		return FALSE;
+
+	return TRUE;
+}
--- a/usr/src/cmd/hal/hald/util.h	Sun Sep 27 11:34:46 2009 +0800
+++ b/usr/src/cmd/hal/hald/util.h	Sun Sep 27 11:48:10 2009 +0800
@@ -109,4 +109,7 @@
 void
 hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed, const char *service, int uid);
 
+gboolean
+is_valid_interface_name (const char *name);
+
 #endif /* UTIL_H */