kern/104389: sys/geom/geom_dump.c doesn't encode XML entities

douglas steinwand dzs-pr at dzs.fx.org
Fri Oct 13 13:50:41 PDT 2006


>Number:         104389
>Category:       kern
>Synopsis:       sys/geom/geom_dump.c doesn't encode XML entities
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 13 20:50:19 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     douglas steinwand
>Release:        6.2-PRERELEASE
>Organization:
>Environment:
FreeBSD sun-x2100.fx.org 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #1: Fri Oct 13 07:15:37 PDT 2006     root at sun-x2100.fx.org:/usr/obj/usr/src/sys/HAWK6-SMP  amd64
>Description:
The sysctl kern.geom.confxml can return invalid XML if, for example, the label has characters that are not safe in XML. This breaks libgeom's geom_xml2tree and utilities that use it, like glabel and gstat.
>How-To-Repeat:
# glabel list
# mdconfig -at swap -s 1m
md0
# glabel create bread\&butter /dev/md0
GEOM_LABEL: Label for provider md0 is label/bread&butter.
# glabel list
Cannot get GEOM tree: Unknown error: -1.
# gstat
gstat: geom_gettree = -1: Unknown error: 0

>Fix:
geom_dump.c should encode XML entities. Attached is a patch.





Patch attached with submission follows:

--- sys/geom/geom_dump.c.orig	Wed Mar 10 00:49:08 2004
+++ sys/geom/geom_dump.c	Fri Oct 13 13:04:11 2006
@@ -45,6 +45,43 @@
 #include <geom/geom.h>
 #include <geom/geom_int.h>
 
+static void
+_encode_entities(char *d, size_t dlen, const char *s)
+{
+	const char *e;
+	char *t;
+
+	if (dlen < 1)
+		return;
+	for(; *s && dlen > 1; s++) {
+		switch(*s) {
+		case '&':
+			e = "&amp;";
+			break;
+		case '<':
+			e = "&lt;";
+			break;
+		case '>':
+			e = "&gt;";
+			break;
+		case '\'':
+			e = "&apos;";
+			break;
+		case '"':
+			e = "&quot;";
+			break;
+		default:
+			*d++ = *s;
+			dlen--;
+			continue;
+		}
+		for(t = d; *e && dlen >= 1; e++, d++, dlen--)
+			*d = *e;
+		if (dlen < 1)
+			d = t;
+	}
+	*d = 0;
+}
 
 static void
 g_confdot_consumer(struct sbuf *sb, struct g_consumer *cp)
@@ -177,12 +214,14 @@
 static void
 g_conf_provider(struct sbuf *sb, struct g_provider *pp)
 {
+	char buf[128];
 
 	sbuf_printf(sb, "\t<provider id=\"%p\">\n", pp);
 	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", pp->geom);
 	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
 	    pp->acr, pp->acw, pp->ace);
-	sbuf_printf(sb, "\t  <name>%s</name>\n", pp->name);
+	_encode_entities(buf, sizeof(buf), pp->name);
+	sbuf_printf(sb, "\t  <name>%s</name>\n", buf);
 	sbuf_printf(sb, "\t  <mediasize>%jd</mediasize>\n",
 	    (intmax_t)pp->mediasize);
 	sbuf_printf(sb, "\t  <sectorsize>%u</sectorsize>\n", pp->sectorsize);
@@ -202,10 +241,12 @@
 {
 	struct g_consumer *cp2;
 	struct g_provider *pp2;
+	char buf[128];
 
 	sbuf_printf(sb, "    <geom id=\"%p\">\n", gp);
 	sbuf_printf(sb, "      <class ref=\"%p\"/>\n", gp->class);
-	sbuf_printf(sb, "      <name>%s</name>\n", gp->name);
+	_encode_entities(buf, sizeof(buf), gp->name);
+	sbuf_printf(sb, "      <name>%s</name>\n", buf);
 	sbuf_printf(sb, "      <rank>%d</rank>\n", gp->rank);
 	if (gp->flags & G_GEOM_WITHER)
 		sbuf_printf(sb, "      <wither/>\n");
@@ -232,9 +273,11 @@
 g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
 {
 	struct g_geom *gp2;
+	char buf[128];
 
 	sbuf_printf(sb, "  <class id=\"%p\">\n", mp);
-	sbuf_printf(sb, "    <name>%s</name>\n", mp->name);
+	_encode_entities(buf, sizeof(buf), mp->name);
+	sbuf_printf(sb, "    <name>%s</name>\n", buf);
 	LIST_FOREACH(gp2, &mp->geom, geom) {
 		if (gp != NULL && gp != gp2)
 			continue;

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list