Only return file descriptors to block or character devices
authorkn <kn@openbsd.org>
Thu, 25 Aug 2022 17:09:54 +0000 (17:09 +0000)
committerkn <kn@openbsd.org>
Thu, 25 Aug 2022 17:09:54 +0000 (17:09 +0000)
If the requested path contained a slash, opendev(3) blindly opened the file
and returned a file descriptor to it.

Check for block or character devices (according to OPENDEV_BLCK) and fail
for other types.

Spotted through installboot(8) which happily opened a stage file as device
when forgetting the device argument:
# installboot -v ./biosboot
Using / as root
installing bootstrap on ./biosboot
using first-stage /usr/mdec/biosboot, second-stage /usr/mdec/boot
installboot: disklabel: ./biosboot: Inappropriate ioctl for device

This makes it fail earlier, as expected:
# installboot -v ./biosboot
installboot: open: ./biosboot: Block device required

The case where opendev(3) is passed a string not containing a slash, i.e.
a supposed DUID, is fine, as diskmap(4) will ensure that only valid device
paths are returned, if the DUID is valid.

Feedback OK millert

lib/libutil/opendev.3
lib/libutil/opendev.c

index 65535a6..ae6ce34 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: opendev.3,v 1.22 2015/01/15 19:06:32 schwarze Exp $
+.\"    $OpenBSD: opendev.3,v 1.23 2022/08/25 17:09:54 kn Exp $
 .\"
 .\" Copyright (c) 2000, Todd C. Miller.  All rights reserved.
 .\" Copyright (c) 1996, Jason Downs.  All rights reserved.
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: January 15 2015 $
+.Dd $Mdocdate: August 25 2022 $
 .Dt OPENDEV 3
 .Os
 .Sh NAME
@@ -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 0be447d..2afbe8d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: opendev.c,v 1.15 2011/06/30 15:04:58 jsing Exp $      */
+/*     $OpenBSD: opendev.c,v 1.16 2022/08/25 17:09:54 kn Exp $ */
 
 /*
  * Copyright (c) 2000, Todd C. Miller.  All rights reserved.
@@ -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,23 @@ opendev(const char *path, int oflags, int dflags, char **realpath)
                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;
+                       } else 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) {