[email protected] (Joel Sing) - Thu, Nov 28, 2013 at 03:16:20AM +1100
> From a quick glance, you should be able to use opendev(3) to open the disk 
> device (rather than using open), in which case you'll get DUID handling for 
> free. This also avoids the TOCTOU issues associated with attempting to map a 
> DUID back to a name. Even if this is not possible, then it would be 
> preferable to use opendev(3) to get the realname (as is done in fsck(8) from 
> memory), rather than the hand rolled version below.

thanks joel. round two is inline below.

Index: Makefile
===================================================================
RCS file: /cvs/src/sbin/dump/Makefile,v
retrieving revision 1.11
diff -p -u -r1.11 Makefile
--- Makefile    6 Jan 2013 21:59:28 -0000       1.11
+++ Makefile    29 Nov 2013 19:26:23 -0000
@@ -12,6 +12,8 @@
 #      TDEBUG                  trace out the process forking
 
 PROG=  dump
+LDADD= -lutil
+DPADD= ${LIBUTIL}
 LINKS= ${BINDIR}/dump ${BINDIR}/rdump
 CFLAGS+=-DRDUMP
 SRCS=  itime.c main.c optr.c dumprmt.c tape.c traverse.c
Index: dump.h
===================================================================
RCS file: /cvs/src/sbin/dump/dump.h,v
retrieving revision 1.17
diff -p -u -r1.17 dump.h
--- dump.h      11 Jun 2013 16:42:04 -0000      1.17
+++ dump.h      29 Nov 2013 19:26:23 -0000
@@ -86,6 +86,7 @@ int   tp_bshift;      /* log2(TP_BSIZE) */
 /* operator interface functions */
 void   broadcast(char *message);
 time_t do_stats(void);
+char   *duidtorawname(char *duid, char *buf, size_t s);
 void   lastdump(int arg);      /* int should be char */
 void   msg(const char *fmt, ...)
     __attribute__((__format__ (printf, 1, 2)));
Index: main.c
===================================================================
RCS file: /cvs/src/sbin/dump/main.c,v
retrieving revision 1.46
diff -p -u -r1.46 main.c
--- main.c      16 Apr 2013 18:17:39 -0000      1.46
+++ main.c      29 Nov 2013 19:26:23 -0000
@@ -51,6 +51,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "dump.h"
 #include "pathnames.h"
@@ -204,7 +205,9 @@ main(int argc, char *argv[])
        for (i = 0; i < argc; i++) {
                struct stat sb;
 
-               if (lstat(argv[i], &sb) == -1) {
+               if (isduid(argv[i], 0))
+                       break;
+               else if (lstat(argv[i], &sb) == -1) {
                        msg("Cannot lstat %s: %s\n", argv[i], strerror(errno));
                        exit(X_STARTUP);
                }
@@ -341,7 +344,8 @@ main(int argc, char *argv[])
                }
        } else if ((dt = fstabsearch(disk)) != NULL) {
                /* in fstab? */
-               disk = rawname(dt->fs_spec);
+               if (!isduid(disk, 0))
+                       disk = rawname(dt->fs_spec);
                mount_point = dt->fs_file;
                (void)strlcpy(spcl.c_dev, dt->fs_spec, sizeof(spcl.c_dev));
                if (dirlist != 0) {
@@ -378,7 +382,7 @@ main(int argc, char *argv[])
        else
                msgtail("to %s\n", tape);
 
-       if ((diskfd = open(disk, O_RDONLY)) < 0) {
+       if ((diskfd = opendev(disk, O_RDONLY, 0, NULL)) < 0) {
                msg("Cannot open %s\n", disk);
                exit(X_STARTUP);
        }
@@ -605,16 +609,39 @@ sig(int signo)
 }
 
 char *
+duidtorawname(char *duid, char *buf, size_t s)
+{
+       char *rp;
+       int fd;
+
+       if (s)
+               buf[0] = '\0';
+
+       if ((fd = opendev(duid, O_RDONLY, 0, &rp)) < 0)
+               return NULL;
+
+       close(fd);
+       strlcpy(buf, rp, s);
+
+       return buf;
+}
+
+char *
 rawname(char *cp)
 {
        static char rawbuf[MAXPATHLEN];
-       char *dp = strrchr(cp, '/');
-
-       if (dp == NULL)
-               return (NULL);
-       *dp = '\0';
-       (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1);
-       *dp = '/';
+       char *dp;
+       
+       if (isduid(cp, 0))
+               return duidtorawname(cp, rawbuf, sizeof(rawbuf));
+       else {
+               dp = strrchr(cp, '/');
+               if (dp == NULL)
+                       return (NULL);
+               *dp = '\0';
+               (void)snprintf(rawbuf, sizeof(rawbuf), "%s/r%s", cp, dp + 1);
+               *dp = '/';
+       }
        return (rawbuf);
 }
 
Index: optr.c
===================================================================
RCS file: /cvs/src/sbin/dump/optr.c,v
retrieving revision 1.34
diff -p -u -r1.34 optr.c
--- optr.c      12 Nov 2013 04:59:02 -0000      1.34
+++ optr.c      29 Nov 2013 19:26:23 -0000
@@ -47,6 +47,7 @@
 #include <tzfile.h>
 #include <unistd.h>
 #include <utmp.h>
+#include <util.h>
 
 #include "dump.h"
 #include "pathnames.h"
@@ -335,17 +336,23 @@ getfstab(void)
 struct fstab *
 fstabsearch(char *key)
 {
+       char keyrn[MAXPATHLEN];
        struct pfstab *pf;
        struct fstab *fs;
        char *rn;
 
+       keyrn[0] = '\0';
+       if (isduid(key, 0))
+               duidtorawname(key, keyrn, sizeof(keyrn));
+
        for (pf = table; pf != NULL; pf = pf->pf_next) {
                fs = pf->pf_fstab;
                if (strcmp(fs->fs_file, key) == 0 ||
                    strcmp(fs->fs_spec, key) == 0)
                        return (fs);
                rn = rawname(fs->fs_spec);
-               if (rn != NULL && strcmp(rn, key) == 0)
+               if (rn != NULL && (strcmp(rn, key) == 0 ||
+                   strcmp(rn, keyrn) == 0))
                        return (fs);
                if (key[0] != '/') {
                        if (*fs->fs_spec == '/' &&
Index: tape.c
===================================================================
RCS file: /cvs/src/sbin/dump/tape.c,v
retrieving revision 1.38
diff -p -u -r1.38 tape.c
--- tape.c      12 Nov 2013 04:59:02 -0000      1.38
+++ tape.c      29 Nov 2013 19:26:23 -0000
@@ -803,7 +803,7 @@ doslave(int cmd, int slave_number)
         * Need our own seek pointer.
         */
        (void) close(diskfd);
-       if ((diskfd = open(disk, O_RDONLY)) < 0)
+       if ((diskfd = opendev(disk, O_RDONLY, 0, NULL)) < 0)
                quit("slave couldn't reopen disk: %s\n", strerror(errno));
 
        /*

Reply via email to