>Number: 149762 >Category: kern >Synopsis: volume labels with rogue characters >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Aug 18 10:20:08 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Walter C. Pelissero >Release: FreeBSD 8.1-STABLE i386 >Organization: >Environment: System: FreeBSD zaphod.home.lan 8.1-STABLE FreeBSD 8.1-STABLE #1: Wed Aug 18 10:09:27 CEST 2010 r...@zaphod.home.lan:/usr/src/sys/i386/compile/TIGER-MP i386
>Description: Labels from external volumes may contain characters that make the label difficult to use for practical purposes. An example is a MSDOS filesystem with whitespace in its label; an fstab entry can't be written for this volume as /etc/fstab has a strict and simple syntax that allows for space only between fields. >How-To-Repeat: Plug a USB dongle with a volume that contains whitespace in the name, such as "foo bar". Now try to write an entry in /etc/fstab for it. >Fix: Although there have been already several proposals, in the past decade, to enhance fstab's syntax (see conf/37569, bin/55539 and bin/117687, conf/149424), this one takes a novel approach: labels are sanitised before creating the entry in /dev/, thus removing the requirement for a new syntax in /etc/fstab In the following patch, the function sanitise_name (controlled by kern.geom.label.sanitation sysctl) replaces characters deemed invalid according to three levels: 0 - replace only '/'s with '#'s 1 - like 0, but also replace whitespace and all the ASCII control characters (anything below 0x20) with '_' 2 - like 1, but also replace anything above 0x7E with '#' Note that the replacement of '/'s is done in any case. I don't know whether that might be redundant or even bad in the context of the other geom_label stuff. It just made sense, but I don't have enough familiarity with that code. =================================================================== RCS file: /repos/src/sys/geom/label/g_label.c,v retrieving revision 1.24.2.4 diff -c -r1.24.2.4 g_label.c *** g_label.c 22 Jun 2010 08:17:20 -0000 1.24.2.4 --- g_label.c 18 Aug 2010 09:48:41 -0000 *************** *** 136,141 **** --- 136,162 ---- return (1); } + static int sanitation_level = 1; + SYSCTL_INT(_kern_geom_label, OID_AUTO, sanitation, CTLFLAG_RW, + &sanitation_level, 0, + "Correction applied to labels: 0 = replace '/'s only, 1 = '/' + whitespace and ctrls, 2 = '/' + anything but ASCII printables"); + + static void + sanitise_name (char *dst, const char *src) + { + for (; *src; ++src, ++dst) { + if (*src == '/') + *dst = '#'; + else if (sanitation_level > 0 && *src <= ' ') + *dst = '_'; + else if (sanitation_level > 1 && *src > '~') + *dst = '#'; + else + *dst = *src; + } + *dst = '\0'; + } + static struct g_geom * g_label_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, const char *label, const char *dir, off_t mediasize) *************** *** 155,161 **** } gp = NULL; cp = NULL; ! snprintf(name, sizeof(name), "%s/%s", dir, label); LIST_FOREACH(gp, &mp->geom, geom) { pp2 = LIST_FIRST(&gp->provider); if (pp2 == NULL) --- 176,185 ---- } gp = NULL; cp = NULL; ! { ! int n = snprintf(name, sizeof(name), "%s/", dir); ! sanitise_name(name + n, label); ! } LIST_FOREACH(gp, &mp->geom, geom) { pp2 = LIST_FIRST(&gp->provider); if (pp2 == NULL) >Release-Note: >Audit-Trail: >Unformatted: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"