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:
parent
bb9abf23e4
commit
f6f04d1a3a
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sys/dirent.h>
|
#include <sys/dirent.h>
|
||||||
#include <fs/cd9660/iso.h>
|
#include <fs/cd9660/iso.h>
|
||||||
#include <fs/cd9660/cd9660_rrip.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,
|
dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||||
int use_rrip, int lenskip)
|
int use_rrip, int lenskip)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len, plen;
|
||||||
char *cp;
|
char *cp, *sep;
|
||||||
int i, icase;
|
int i, icase;
|
||||||
|
|
||||||
if (use_rrip)
|
if (use_rrip)
|
||||||
@ -242,7 +243,14 @@ dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
|||||||
} else
|
} else
|
||||||
icase = 0;
|
icase = 0;
|
||||||
|
|
||||||
if (strlen(path) != len)
|
sep = strchr(path, '/');
|
||||||
|
if (sep != NULL) {
|
||||||
|
plen = sep - path;
|
||||||
|
} else {
|
||||||
|
plen = strlen(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plen != len)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
for (i = len; --i >= 0; path++, cp++) {
|
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 rec;
|
||||||
struct iso_directory_record *dp = NULL;
|
struct iso_directory_record *dp = NULL;
|
||||||
int rc, first, use_rrip, lenskip;
|
int rc, first, use_rrip, lenskip;
|
||||||
|
bool isdir = false;
|
||||||
|
|
||||||
/* First find the volume descriptor */
|
/* First find the volume descriptor */
|
||||||
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
||||||
@ -372,7 +381,24 @@ cd9660_open(const char *path, struct open_file *f)
|
|||||||
rec = *dp;
|
rec = *dp;
|
||||||
while (*path && *path != '/') /* look for next component */
|
while (*path && *path != '/') /* look for next component */
|
||||||
path++;
|
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 */
|
/* allocate file system specific data structure */
|
||||||
|
Loading…
Reference in New Issue
Block a user