Author: tsoome
Date: Wed Feb 20 21:07:09 2019
New Revision: 344387
URL: https://svnweb.freebsd.org/changeset/base/344387

Log:
  loader: really fix cd9660 dirmatch
  
  The cd9660_open() does pass whole path to dirmatch() and we need to
  compare only the current path component, not full path.
  
  Additinally, skip over duplicate / (if any) and check if the last component
  in the path was meant to be directory (having trailing /). If it is in fact
  a file, error out.

Modified:
  head/stand/libsa/cd9660.c

Modified: head/stand/libsa/cd9660.c
==============================================================================
--- head/stand/libsa/cd9660.c   Wed Feb 20 21:06:11 2019        (r344386)
+++ head/stand/libsa/cd9660.c   Wed Feb 20 21:07:09 2019        (r344387)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
  */
 #include <sys/param.h>
 #include <string.h>
+#include <stdbool.h>
 #include <sys/dirent.h>
 #include <fs/cd9660/iso.h>
 #include <fs/cd9660/cd9660_rrip.h>
@@ -227,8 +228,8 @@ static int
 dirmatch(struct open_file *f, const char *path, struct iso_directory_record 
*dp,
     int use_rrip, int lenskip)
 {
-       size_t len;
-       char *cp;
+       size_t len, plen;
+       char *cp, *sep;
        int i, icase;
 
        if (use_rrip)
@@ -242,7 +243,14 @@ dirmatch(struct open_file *f, const char *path, struct
        } else
                icase = 0;
 
-       if (strlen(path) != len)
+       sep = strchr(path, '/');
+       if (sep != NULL) {
+               plen = sep - path;
+       } else {
+               plen = strlen(path);
+       }
+
+       if (plen != len)
                return (0);
 
        for (i = len; --i >= 0; path++, cp++) {
@@ -283,6 +291,7 @@ cd9660_open(const char *path, struct open_file *f)
        struct iso_directory_record rec;
        struct iso_directory_record *dp = NULL;
        int rc, first, use_rrip, lenskip;
+       bool isdir = false;
 
        /* First find the volume descriptor */
        buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
@@ -372,7 +381,24 @@ cd9660_open(const char *path, struct open_file *f)
                rec = *dp;
                while (*path && *path != '/') /* look for next component */
                        path++;
-               if (*path) path++; /* skip '/' */
+
+               if (*path)      /* this component was directory */
+                       isdir = true;
+
+               while (*path == '/')
+                       path++; /* skip '/' */
+
+               if (*path)      /* We do have next component. */
+                       isdir = false;
+       }
+
+       /*
+        * if the path had trailing / but the path does point to file,
+        * report the error ENOTDIR.
+        */
+       if (isdir == true && (isonum_711(rec.flags) & 2) == 0) {
+               rc = ENOTDIR;
+               goto out;
        }
 
        /* allocate file system specific data structure */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to