On Mon, Aug 22, 2022 at 10:38:29AM +0000, Klemens Nanni wrote: > The real problem seems to be that opendev(3) happily opens a regular > file as device, but only if the argument contains a slash: > > # installboot -v ./biosboot > Using / as root > installing bootstrap on ./biosboot > using first-stage /usr/mdec/biosboot, second-stage /usr/mdec/boot > > # installboot -v biosboot > installboot: open: /dev/rbiosboot: No such file or directory > > This points at the same file and "biosboot" is obviously neither a short > form device name nor a DUID.
opendev(3) blindly open(2)s its path argument and returns the return code if the path contains a slash -- no checks are performed, which results in usages like the first demo. If path has no slash, it is taken as DUID and diskmap(4) makes sure that it either maps to a valid device or fails, see the second usage. Make opendev(3) require a character (or block if OPENDEV_BLCK is passed) and fail otherwise, yielding a more accurate: $ doas ./obj/installboot -v /usr/mdec/biosboot installboot: open: ./Makefile: Block device required This seems much clearer and prevents tools from openening arbitrary files as "devices". Feedback? Am I missing anything? Index: opendev.3 =================================================================== RCS file: /cvs/src/lib/libutil/opendev.3,v retrieving revision 1.22 diff -u -p -r1.22 opendev.3 --- opendev.3 15 Jan 2015 19:06:32 -0000 1.22 +++ opendev.3 24 Aug 2022 19:34:20 -0000 @@ -90,10 +90,12 @@ is not .Dv NULL , it is modified to point at the fully expanded device name. .Sh RETURN VALUES -The +If successful, .Fn opendev -return value and errors are the same as the return value and errors of -.Xr open 2 . +returns a file descriptor. +Otherwise, a value of -1 is returned and +.Va errno +is set to indicate the error. .Sh SEE ALSO .Xr open 2 , .Xr getrawpartition 3 , Index: opendev.c =================================================================== RCS file: /cvs/src/lib/libutil/opendev.c,v retrieving revision 1.15 diff -u -p -r1.15 opendev.c --- opendev.c 30 Jun 2011 15:04:58 -0000 1.15 +++ opendev.c 24 Aug 2022 19:54:25 -0000 @@ -38,6 +38,7 @@ #include <sys/limits.h> #include <sys/disk.h> #include <sys/dkio.h> +#include <sys/stat.h> #include "util.h" @@ -63,8 +64,25 @@ opendev(const char *path, int oflags, in prefix = "r"; /* character device */ if ((slash = strchr(path, '/'))) { + struct stat sb; + strlcpy(namebuf, path, sizeof(namebuf)); fd = open(namebuf, oflags); + + if (fd != -1) { + if (fstat(fd, &sb) == -1) { + close(fd); + fd = -1; + } + + if (((dflags & OPENDEV_BLCK) && + !S_ISBLK(sb.st_mode)) || + !S_ISCHR(sb.st_mode)) { + close(fd); + fd = -1; + errno = ENOTBLK; + } + } } else if (isduid(path, dflags)) { strlcpy(namebuf, path, sizeof(namebuf)); if ((fd = open("/dev/diskmap", oflags)) != -1) {