[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));
/*