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.
This commit is contained in:
tsoome 2019-02-20 21:07:09 +00:00
parent bb9abf23e4
commit f6f04d1a3a

View File

@ -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 iso_directory_record *dp,
} 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 */