mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-27 16:39:08 +00:00
Simplify the handling of a fragmented file_id descriptor. Also
de-obfuscate the file_char flags.
This commit is contained in:
parent
97c54f7797
commit
2bbe0d3617
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101317
@ -318,6 +318,11 @@ struct fileid_desc {
|
||||
uint8_t data[1];
|
||||
} __attribute__ ((packed));
|
||||
#define UDF_FID_SIZE 38
|
||||
#define UDF_FILE_CHAR_VIS (1 << 0) /* Visible */
|
||||
#define UDF_FILE_CHAR_DIR (1 << 1) /* Directory */
|
||||
#define UDF_FILE_CHAR_DEL (1 << 2) /* Deleted */
|
||||
#define UDF_FILE_CHAR_PAR (1 << 3) /* Parent Directory */
|
||||
#define UDF_FILE_CHAR_META (1 << 4) /* Stream metadata */
|
||||
|
||||
/* File Entry [4/14.9] */
|
||||
struct file_entry {
|
||||
|
@ -546,7 +546,7 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
struct fileid_desc *fid;
|
||||
struct udf_uiodir uiodir;
|
||||
u_long *cookies = NULL;
|
||||
uint8_t *data;
|
||||
uint8_t *data, *buf;
|
||||
int ncookies;
|
||||
int error = 0, offset, off, size, de_size, fid_size, fsize;
|
||||
int total_fid_size = 0, frag_size = 0, fid_fragment = 0;
|
||||
@ -611,19 +611,24 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
*/
|
||||
if (off + fid_size > size ||
|
||||
off + fid->l_iu + fid->l_fi + fid_size > size) {
|
||||
struct fileid_desc *fid_buf;
|
||||
uint8_t *buf;
|
||||
|
||||
/* Copy what we have of the fid into a buffer */
|
||||
frag_size = size - off;
|
||||
MALLOC(buf, uint8_t*, max(frag_size, fid_size),
|
||||
M_UDFFID, M_NOWAIT | M_ZERO);
|
||||
if (buf == NULL)
|
||||
panic("No memory?");
|
||||
if (frag_size >= udfmp->bsize) {
|
||||
printf("udf: invalid FID fragment\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* File ID descriptors can only be at most one
|
||||
* logical sector in size.
|
||||
*/
|
||||
MALLOC(buf, uint8_t*, udfmp->bsize, M_UDFFID,
|
||||
M_WAITOK | M_ZERO);
|
||||
bcopy(fid, buf, frag_size);
|
||||
|
||||
/* Reduce all of the casting magic */
|
||||
fid_buf = (struct fileid_desc*)buf;
|
||||
fid = (struct fileid_desc*)buf;
|
||||
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
@ -646,26 +651,18 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
|
||||
/*
|
||||
* Now that we have enough of the fid to work with,
|
||||
* allocate a new fid, copy the fragment into it,
|
||||
* and copy the rest of the fid from the new
|
||||
* copy in the rest of the fid from the new
|
||||
* allocation.
|
||||
*/
|
||||
total_fid_size = fid_size + fid_buf->l_iu +
|
||||
fid_buf->l_fi;
|
||||
MALLOC(fid, struct fileid_desc *, total_fid_size,
|
||||
M_UDFFID, M_NOWAIT | M_ZERO);
|
||||
if (fid == NULL) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
error = ENOMEM;
|
||||
total_fid_size = fid_size + fid->l_iu + fid->l_fi;
|
||||
if (total_fid_size > udfmp->bsize) {
|
||||
printf("udf: invalid FID\n");
|
||||
break;
|
||||
}
|
||||
bcopy(fid_buf, fid, frag_size);
|
||||
bcopy(data, &((uint8_t*)(fid))[frag_size],
|
||||
bcopy(data, &buf[frag_size],
|
||||
total_fid_size - frag_size);
|
||||
|
||||
fid_fragment = 1;
|
||||
FREE(buf, M_UDFFID);
|
||||
} else {
|
||||
total_fid_size = fid->l_iu + fid->l_fi + fid_size;
|
||||
}
|
||||
@ -677,7 +674,7 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
}
|
||||
|
||||
/* Is this a deleted file? */
|
||||
if (fid->file_char & 0x4)
|
||||
if (fid->file_char & UDF_FILE_CHAR_DEL)
|
||||
goto update_offset;
|
||||
|
||||
if (fid->l_iu != 0) {
|
||||
@ -685,7 +682,7 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
goto update_offset;
|
||||
}
|
||||
|
||||
if ((fid->l_fi == 0) && (fid->file_char & 0x08)) {
|
||||
if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
|
||||
/* Do up the '.' and '..' entries. Dummy values are
|
||||
* used for the cookies since the offset here is
|
||||
* usually zero, and NFS doesn't like that value
|
||||
@ -704,8 +701,8 @@ udf_readdir(struct vop_readdir_args *a)
|
||||
dir.d_namlen = udf_transname(&fid->data[fid->l_iu],
|
||||
&dir.d_name[0], fid->l_fi);
|
||||
dir.d_fileno = udf_getid(&fid->icb);
|
||||
dir.d_type = (fid->file_char & 0x02) ? DT_DIR :
|
||||
DT_UNKNOWN;
|
||||
dir.d_type = (fid->file_char & UDF_FILE_CHAR_DIR) ?
|
||||
DT_DIR : DT_UNKNOWN;
|
||||
dir.d_reclen = GENERIC_DIRSIZ(&dir);
|
||||
uiodir.dirent = &dir;
|
||||
error = udf_uiodir(&uiodir, dir.d_reclen, uio, off);
|
||||
@ -847,10 +844,10 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
char *nameptr;
|
||||
long namelen;
|
||||
ino_t id = 0;
|
||||
uint8_t *data;
|
||||
uint8_t *data, *buf;
|
||||
int offset, off, error, size;
|
||||
int numdirpasses, fid_size, fsize, icb_len;
|
||||
int total_fid_size = 0, fid_fragment = 0;
|
||||
int total_fid_size = 0, fid_fragment = 0, frag_size = 0;
|
||||
|
||||
dvp = a->a_dvp;
|
||||
node = VTON(dvp);
|
||||
@ -900,20 +897,24 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
*/
|
||||
if (off + fid_size > size ||
|
||||
off + fid_size + fid->l_iu + fid->l_fi > size) {
|
||||
struct fileid_desc *fid_buf;
|
||||
uint8_t *buf;
|
||||
int frag_size = 0;
|
||||
|
||||
/* Copy what we have of the fid into a buffer */
|
||||
frag_size = size - off;
|
||||
MALLOC(buf, uint8_t*, max(frag_size, fid_size),
|
||||
M_UDFFID, M_NOWAIT | M_ZERO);
|
||||
if (buf == NULL)
|
||||
panic("No memory?");
|
||||
if (frag_size >= udfmp->bsize) {
|
||||
printf("udf: invalid FID fragment\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* File ID descriptors can only be at most one
|
||||
* logical sector in size.
|
||||
* Copy what we have of the fid into a buffer
|
||||
*/
|
||||
MALLOC(buf, uint8_t*, udfmp->bsize, M_UDFFID,
|
||||
M_WAITOK | M_ZERO);
|
||||
bcopy(fid, buf, frag_size);
|
||||
|
||||
/* Reduce all of the casting magic */
|
||||
fid_buf = (struct fileid_desc*)buf;
|
||||
fid = (struct fileid_desc*)buf;
|
||||
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
@ -936,26 +937,19 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
|
||||
/*
|
||||
* Now that we have enough of the fid to work with,
|
||||
* allocate a new fid, copy the fragment into it,
|
||||
* and copy the rest of the fid from the new
|
||||
* copy the rest of the fid from the new
|
||||
* allocation.
|
||||
*/
|
||||
total_fid_size = fid_size + fid_buf->l_iu +
|
||||
fid_buf->l_fi;
|
||||
MALLOC(fid, struct fileid_desc *, total_fid_size,
|
||||
M_UDFFID, M_NOWAIT | M_ZERO);
|
||||
if (fid == NULL) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
return (ENOMEM);
|
||||
total_fid_size = fid_size + fid->l_iu + fid->l_fi;
|
||||
if (total_fid_size > udfmp->bsize) {
|
||||
printf("udf: invalid FID\n");
|
||||
break;
|
||||
}
|
||||
bcopy(fid_buf, fid, frag_size);
|
||||
bcopy(data, &((uint8_t*)(fid))[frag_size],
|
||||
bcopy(data, &buf[frag_size],
|
||||
total_fid_size - frag_size);
|
||||
|
||||
off = (total_fid_size - frag_size + 3) & ~0x03;
|
||||
fid_fragment = 1;
|
||||
FREE(buf, M_UDFFID);
|
||||
} else {
|
||||
/*
|
||||
* Update the offset here to avoid looking at this fid
|
||||
@ -970,10 +964,10 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
goto continue_lookup;
|
||||
|
||||
/* Is this a deleted file? */
|
||||
if (fid->file_char & 0x4)
|
||||
if (fid->file_char & UDF_FILE_CHAR_DEL)
|
||||
goto continue_lookup;
|
||||
|
||||
if ((fid->l_fi == 0) && (fid->file_char & 0x08)) {
|
||||
if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
|
||||
if (flags & ISDOTDOT) {
|
||||
id = udf_getid(&fid->icb);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user