Date: Tue, 03 Sep 2019 14:05:53 -0000 From: Toomas Soome <tsoome@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r345631 - stable/12/stand/libsa Message-ID: <201903280838.x2S8cVci097891@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903280838.x2S8cVci097891>