The openpartition function in tunefs(8) will currently set devicep, a
char** passed in from main, to the path it attempted to opendev(3).
This doesn't actually work as intended; it should be setting the value
devicep points to instead of devicep itself.

Also, section 6.9.1 clause 9 of C99[0] says that "each parameter has
automatic storage duration", so I think it's not safe to rely on a
function parameter still being a valid object outside of openpartition
(please correct me if I'm wrong on that).

The diff below addresses both of these issues, and while here, also
cleans up some path-wrangling baggage dating from prior to opendev(3).

[0] http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

Index: tunefs.c
===================================================================
RCS file: /cvs/src/sbin/tunefs/tunefs.c,v
retrieving revision 1.37
diff -u -p -r1.37 tunefs.c
--- tunefs.c    7 Feb 2015 02:09:14 -0000       1.37
+++ tunefs.c    23 Aug 2015 09:11:58 -0000
@@ -309,21 +309,22 @@ bread(daddr_t blk, char *buffer, int cnt
 static int
 openpartition(char *name, int flags, char **devicep)
 {
-       char            rawspec[PATH_MAX], *p;
+       static char     realname[PATH_MAX];
+       char            *p;
        struct fstab    *fs;
        int             fd;
 
        fs = getfsfile(name);
        if (fs) {
-               if ((p = strrchr(fs->fs_spec, '/')) != NULL) {
-                       snprintf(rawspec, sizeof(rawspec), "%.*s/r%s",
-                           (int)(p - fs->fs_spec), fs->fs_spec, p + 1);
-                       name = rawspec;
-               } else
-                       name = fs->fs_spec;
+               name = fs->fs_spec;
+               if ((p = strrchr(name, '/')) != NULL)
+                       name = p + 1;
        }
        fd = opendev(name, flags, 0, devicep);
-       if (fd == -1 && errno == ENOENT)
-               devicep = &name;
+       if (fd == -1 && errno == ENOENT) {
+               /* Only used in err(3), truncation is ok. */
+               (void)strlcpy(realname, name, sizeof(realname));
+               *devicep = realname;
+       }
        return (fd);
 }

Reply via email to