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) {

Reply via email to