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).
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 05:34: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,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) {