svn commit: r345631 - stable/12/stand/libsa

Toomas Soome tsoome at FreeBSD.org
Thu Mar 28 08:38:33 UTC 2019


Author: tsoome
Date: Thu Mar 28 08:38:31 2019
New Revision: 345631
URL: https://svnweb.freebsd.org/changeset/base/345631

Log:
  MFC: r344248,r344387
  
  cd9660: dirmatch fails to unmatch when name is prefix for directory record
  
  Loader does fail to properly match the file name in directory record and
  does open file based on prefix match.
  
  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:
  stable/12/stand/libsa/cd9660.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/stand/libsa/cd9660.c
==============================================================================
--- stable/12/stand/libsa/cd9660.c	Thu Mar 28 08:30:45 2019	(r345630)
+++ stable/12/stand/libsa/cd9660.c	Thu Mar 28 08:38:31 2019	(r345631)
@@ -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)
@@ -241,6 +242,17 @@ dirmatch(struct open_file *f, const char *path, struct
 		icase = 1;
 	} else
 		icase = 0;
+
+	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++) {
 		if (!*path || *path == '/')
 			break;
@@ -279,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);
@@ -368,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 */


More information about the svn-src-all mailing list