From 2533f6f486558681bd73bccc34e7f5b9720d5fb5 Mon Sep 17 00:00:00 2001 From: kn Date: Thu, 25 Aug 2022 17:09:54 +0000 Subject: [PATCH] Only return file descriptors to block or character devices 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 | 12 +++++++----- lib/libutil/opendev.c | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/libutil/opendev.3 b/lib/libutil/opendev.3 index 65535a6fdde..ae6ce343007 100644 --- a/lib/libutil/opendev.3 +++ b/lib/libutil/opendev.3 @@ -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 , diff --git a/lib/libutil/opendev.c b/lib/libutil/opendev.c index 0be447d1323..2afbe8d6586 100644 --- a/lib/libutil/opendev.c +++ b/lib/libutil/opendev.c @@ -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 #include #include +#include #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) { -- 2.20.1