On Thu, Aug 25, 2022 at 05:36:53AM +0000, Klemens Nanni wrote:
> On Wed, Aug 24, 2022 at 08:02:03PM -0600, Todd C. Miller wrote:
> > On Wed, 24 Aug 2022 20:06:00 -0000, Klemens Nanni wrote:
> > 
> > > Feedback? Am I missing anything?
> > 
> > If fstat(2) fails you should not try to access sb.  Perhaps:
> > 
> >     if (((dflags & OPENDEV_BLCK) && ...
> > 
> > should be an "else if (..."
> 
> Ah yes, the failure check does not return early but falls through, so
> all further logic needs to check fd and/or errno (like the isduid() case
> already does).

> +                     } else if (((dflags & OPENDEV_BLCK) &&
> +                         !S_ISBLK(sb.st_mode)) ||
> +                         !S_ISCHR(sb.st_mode)) {

And this should use the ternary operator, as this would still succeed
if path is a character device even though OPENDEV_BLCK was passed.

OK?


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   25 Aug 2022 11:46:26 -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,23 @@ 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;
+                       } 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) {

Reply via email to