--- old/usr/src/cmd/svc/svccfg/svccfg_xml.c	2015-09-16 00:43:13.498911667 +0300
+++ new/usr/src/cmd/svc/svccfg/svccfg_xml.c	2015-09-16 00:43:13.504445722 +0300
@@ -21,6 +21,10 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ */
+
 
 /*
  * XML document manipulation routines
@@ -580,9 +584,7 @@
 	case SC_USTRING:
 		scf_type = lxml_element_to_type(type);
 
-		if ((v->sc_u.sc_string = strdup((char *)value)) == NULL)
-			uu_die(gettext("string duplication failed (%s)\n"),
-			    strerror(errno));
+		v->sc_u.sc_string = safe_strdup((const char *)value);
 		if (lxml_validate_string_value(scf_type,
 		    v->sc_u.sc_string) != 0)
 			uu_die(gettext("illegal value \"%s\" for "
@@ -1370,7 +1372,7 @@
 	if (((stabval = xmlGetProp(rstr, (xmlChar *)value_attr)) == NULL) ||
 	    (*stabval == 0)) {
 		uu_warn(gettext("no stability value found\n"));
-		stabval = (xmlChar *)strdup("External");
+		stabval = (xmlChar *)safe_strdup("External");
 	}
 
 	pg = internal_pgroup_find_or_create(entity, (char *)scf_pg_general,
@@ -1438,8 +1440,7 @@
 	char *value;
 	char *prop;
 
-	if ((prop = strdup(propname)) == NULL)
-		uu_die(gettext("Out of memory.\n"));
+	prop = safe_strdup(propname);
 
 	value = (char *)xmlGetProp(pval, (xmlChar *)value_attr);
 	if (value == NULL || *value == '\0')
@@ -1455,8 +1456,7 @@
 {
 	property_t *p = internal_property_new();
 
-	if ((p->sc_property_name = strdup(propname)) == NULL)
-		uu_die(gettext("Out of memory.\n"));
+	p->sc_property_name = safe_strdup(propname);
 	p->sc_value_type = SCF_TYPE_ASTRING;
 
 	(void) lxml_get_value(p, SC_ASTRING, param);
@@ -1707,8 +1707,7 @@
 	/*
 	 * Remove leading and trailing whitespace.
 	 */
-	if ((stripped = strdup((const char *)cursor->content)) == NULL)
-		uu_die(gettext("Out of memory\n"));
+	stripped = safe_strdup((const char *)cursor->content);
 
 	for (; isspace(*stripped); stripped++)
 		;
@@ -1944,14 +1943,13 @@
 	char *out, *cp;
 	size_t len, piece_len;
 
-	out = uu_zalloc(2 * scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1);
+	out = uu_zalloc(2 * max_scf_name_len + 1);
 	if (out == NULL)
 		return (NULL);
 
-	(void) strcpy(out, prefix);
-	(void) strcat(out, in);
+	(void) strlcpy(out, prefix, 2 * max_scf_name_len + 1);
 
-	len = strlen(out);
+	len = strlcat(out, in, 2 * max_scf_name_len + 1);
 	if (len > max_scf_name_len) {
 		/* Use the first half and the second half. */
 		piece_len = (max_scf_name_len - 2) / 2;
@@ -1959,8 +1957,6 @@
 		(void) strncpy(out + piece_len, "..", 2);
 
 		(void) strcpy(out + piece_len + 2, out + (len - piece_len));
-
-		len = strlen(out);
 	}
 
 	/*
@@ -1971,8 +1967,6 @@
 			*cp = '_';
 	}
 
-	*cp = '\0';
-
 	return (out);
 }
 
@@ -2036,9 +2030,7 @@
 		v->sc_type = (*p)->sc_value_type;
 		v->sc_free = lxml_free_str;
 		val_str[0] = *seps;
-		v->sc_u.sc_string = strdup(val_str);
-		if (v->sc_u.sc_string == NULL)
-			uu_die(gettext("Out of memory\n"));
+		v->sc_u.sc_string = safe_strdup(val_str);
 		internal_attach_value(*p, v);
 	}
 }
@@ -2083,19 +2075,48 @@
 {
 	pgroup_t *pg;
 	char *pgname;
+	char *name;
 	xmlChar *title;
+	xmlChar *section;
 
 	/*
-	 * Fetch title attribute, convert to something sanitized, and create
-	 * property group.
+	 * Fetch title and section attributes, convert to something sanitized,
+	 * and create property group.
 	 */
 	title = xmlGetProp(manpage, (xmlChar *)title_attr);
-	pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX,
-	    (const char *)title);
+	if (title == NULL)
+		return (-1);
+	section = xmlGetProp(manpage, (xmlChar *)section_attr);
+	if (section == NULL) {
+		xmlFree(title);
+		return (-1);
+	}
+
+	name = safe_malloc(max_scf_name_len + 1);
+
+	/* Find existing property group with underscore separators */
+	(void) snprintf(name, max_scf_name_len + 1, "%s_%s", title, section);
+	pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
+	pg = internal_pgroup_find(service, pgname, SCF_GROUP_TEMPLATE);
+
+	uu_free(pgname);
+	(void) snprintf(name, max_scf_name_len + 1, "%s%s", title, section);
+	pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
+
+	if (pg == NULL) {
+		pg = internal_pgroup_find_or_create(service, pgname,
+		    SCF_GROUP_TEMPLATE);
+	} else {
+		/* Rename property group */
+		free((char *)pg->sc_pgroup_name);
+		pg->sc_pgroup_name = safe_strdup(pgname);
+	}
+
+	uu_free(pgname);
+	free(name);
+	xmlFree(section);
 	xmlFree(title);
 
-	pg = internal_pgroup_find_or_create(service, pgname,
-	    (char *)SCF_GROUP_TEMPLATE);
 
 	/*
 	 * Each attribute is an astring property within the group.
@@ -2123,12 +2144,16 @@
 	 * property group.
 	 */
 	name = xmlGetProp(doc_link, (xmlChar *)name_attr);
+	if (name == NULL)
+		return (-1);
 
 	pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_DOC_PREFIX,
 	    (const char *)name);
 
 	pg = internal_pgroup_find_or_create(service, pgname,
 	    (char *)SCF_GROUP_TEMPLATE);
+
+	uu_free(pgname);
 	xmlFree(name);
 
 	/*
@@ -3668,7 +3693,7 @@
 		return (-1);
 	}
 
-	document->name = strdup(filename);
+	document->name = safe_strdup(filename);
 
 	/*
 	 * Verify that this is a document type we understand.
